Call function if switch gets toggled in VueJS/VuetifyJS - javascript

I'm using VuetifyJS for VueJS and I need to call a function if the switch gets toggled. How to do that?
Template:
<v-container fluid>
<v-switch :label="`Switch 1: ${switch1.toString()}`" v-model="switch1"></v-switch>
</v-container>
</template>
Script:
<script>
export default {
data () {
return {
switch1: false
}
}
}
</script>

Found another better solution to use #change prop, Which calls the method every time the switch is toggled.
<v-switch
:input-value="true"
#change="changeState(item.id)"
></v-switch>
<v-switch
:input-value="true"
#change="changeState(item.id)"
></v-switch>
Here's script,
methods:{
changeState(id) {
console.log("Switch "+id);
// Do stuff
}
}

You can set up a watcher on switch1 data property as follows:
<script>
export default {
data () {
return {
switch1: false
}
},
watch: {
switch1(newValue){
//called whenever switch1 changes
console.log(newValue);
}
}
}
</script>
Since the v-model of v-switch is bound to switch1 , whenever the switch is toggled on/off the watch handler of switch1 gets called with the changed newValue
Here is a codepen

Related

Vuetify 3 change event in v-select

I am testing Vuetify 3 (npm:#vuetify/nightly#next) v-select and try to get change event. However, my handler function is not called. This is my code:
TS:
export default defineComponent({
setup() {
function onLanguageChange(a: any) {
console.log(a);
}
const items = ['Русский', 'English'];
return {onLanguageChange, items}
}
});
Vue
<v-select
prepend-icon="mdi-web"
:items="items"
label="Lang"
#change="onLanguageChange"
></v-select>
And this is what I get in console when I focus select and change its value.
Could anyone say, if this is a bug or something is wrong with my code (and how to fix it)?
v-select's event list does not include the change event. It only has one event: update:modelValue.
Use the update:modelValue event instead:
<v-select #update:modelValue="onLanguageChange">
demo 1
Or use a v-model with a watcher:
<v-select v-model="lang">...</v-select>
import { ref, watch } from 'vue'
export default {
setup() {
const lang = ref()
watch(lang, (newValue) => console.log('new lang', newValue))
return { lang }
}
}
demo 2

Vuetify trigger a tooltip

I'm using vuetify, and I have a tooltip over a button.
I doesn't want to show the tooltip on hover nor on click, I want to show the tooltip if some event is triggered.
translate.vue
<v-tooltip v-model="item.showTooltip" top>
<template v-slot:activator="{}">
<v-btn #click="translateItem(item)"> Call API to translate</v-btn>
</template>
<span>API quota limit has been reached</span>
</v-tooltip>
<script>
export default(){
props: {
item: { default: Objet}
}
methods: {
translateItem: function (item) {
axios
.post(baseURL + "/translateAPI", {
text: item.originTrad;
})
.then((res) => {
if (apiQuotaLimitReached(res) {
// If limit is reached I want to show the tooltip for some time
item.showTooltip = true;
setTimeout(() => {item.showTooltip = false;}, 3000);
} else { ..... }}}
</script>
itemSelect.vue (where I create object item and then use router push to transmit it to the translation page)
<script>
export default(){
methods: {
createItem: function () {
item.originTrad = "the text to translate"
....
item.showTooltip = false;
this.$router.push({
name: "translate",
params: {
"item": item,
},
}); }}
</script>
As you can see I removed the v-slot:activator="{ on }" and v-on="on" that I found on the exemple:https://vuetifyjs.com/fr-FR/components/tooltips/ , because I don't want to show the tooltip on hover. But It doesn't work as expected, the tooltip is not showing properly.
Some help would be great :)
For starters, you are trying to change a prop in the child component, something that you should not do:
[Vue warn]: Avoid mutating a prop directly since the value will be
overwritten whenever the parent component re-renders. Instead, use a
data or computed property based on the prop's value. Prop being
mutated: "item.showTooltip"
So start by making a separate data variable for showTooltip (doesn't need to be a property of item perse) and try setting it to true to see what happens (and of course change v-model="item.showTooltip" to v-model="showTooltip" on v-tooltip)

Properly using click:outside with vuetify dialog

I have a v-dialog that I use to pop up a date picker when needed. To show it, I bind a value with v-modle. I use the click:outside events to trigger to function that is supposed to close it once it's clicked outside so I can trigger it again (if I click outside, the dialog is dismissed, but the value stays 'true', so I can't show it more than once). There must be something I'm doing wrong.
Here's my dialog :
<template>
<v-dialog
v-model="value"
#click:outside="closeDialog"
>
<v-date-picker
v-model="date"
/>
<v-divider/>
<div>fermer</div>
</v-dialog>
</template>
<script>
export default {
name: 'DatePickerDialog',
props: ['value'],
data() {
return {
colors,
date: null,
}
},
methods: {
closeDialog() {
this.value = false;
}
}
}
</script>
And what calls it is as simple as this :
<template>
<div>
<v-btn #click="inflateDatePicker">inflate date picker</v-btn>
<date-picker-dialog v-model="showDatePicker"/>
</div>
</template>
<script>
import DatePickerDialog from '../../../../views/components/DatePickerDialog';
export default{
name: "SimpleTest",
components: {
DatePickerDialog
},
data() {
return {
showDatePicker: false,
};
},
methods:{
inflateDatePicker() {
this.showDatePicker = true;
},
},
}
</script>
So I can inflate it with no problem. Then though I'm not able to go inside closeDialog() (verified by debugging and trying to log stuff). So what is happening that makes it so I'm not able to enter the function? Documentation doesn't specify if you need to use it differently from regular #click events
The problem was in my closeDialog function. this.value = false did not notify the parent component of the value change. So I had to change it to this in order for it to work properly :
closeDialog() {
this.$emit('input', false);
},
With this is works perfectly fine.

Vuex do not mutate vuex store state outside mutation handlers - Vuetify

I am building a nuxt app with Vuetify. My use case is that i want to implement a global bottom-sheet.
My code below works fine until when i click outside the sheet and it throws an error.
What am I missing below?
Error: [vuex] do not mutate vuex store state outside mutation handlers.
What i have tried so far.
<template>
<div>
<v-bottom-sheet v-model="$store.state.sheet">
<v-card>
<v-card-title>Hi there</v-card-title>
<v-card-subtitle>This is a demo sheet</v-card-subtitle>
</v-card>
</v-bottom-sheet>
<v-btn class="mt-5" #click="openSheet">Sheet</v-btn>
</div>
</template>
<script>
export default {
methods: {
openSheet() {
this.$store.commit("openSheet");
}
}
};
</script>
Store/index.js
export const state = () => ({
sheet: false
})
export const mutations = {
openSheet(state){
state.sheet = !state.sheet
}
}
When you clicked outsise, you tried to modify the state directly. You need to mofify it with a mutation, one way is to create a computed property and set it to v-model:
<template>
<div>
<v-bottom-sheet v-model="sheet">
<v-card>
<v-card-title>Hi there</v-card-title>
<v-card-subtitle>This is a demo sheet</v-card-subtitle>
</v-card>
</v-bottom-sheet>
<v-btn class="mt-5" #click="openSheet">Sheet</v-btn>
</div>
</template>
<script>
export default {
computed: {
sheet: {
get () {
return this.$store.state.sheet;
},
set (value) {
this.$store.commit("openSheet");
}
}
},
methods: {
openSheet() {
this.$store.commit("openSheet");
}
}
};

Can't open Vuetify dialog programmatically in setTimeout callback

By default, the displaying of Vuetify dialog is controlled by a button toggling the value of dialog Boolean variable.
I was assuming that programmatically changing the value of this variable would allow to show or hide the dialog, but it doesn't. Why not?
Here's my code:
<template>
<div>
<v-dialog v-model="dialog">
<v-card>
Dialog content
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
data() {
return {
dialog: false
}
},
mounted() {
console.log(this.dialog);
setTimeout(function() {
this.dialog = true;
console.log(this.dialog);
}, 2000);
}
}
</script>
Console shows false on page load, then true after 2 seconds. But dialog still doesn't show up...
You should use arrow function ()=> as setTimeout callback :
mounted() {
console.log(this.dialog);
setTimeout(()=> {
this.dialog = true;
console.log(this.dialog);
}, 2000);
}
See the Pen
Vuetify Dialog example by boussadjra (#boussadjra)
on CodePen.
you're having some trouble calling the variable inside the function of the setTimeout.
try this:
<template>
<div>
<v-dialog v-model="dialog">
<v-card>
Dialog content
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
data() {
return {
dialog: false
}
},
mounted() {
that = this
console.log(this.dialog);
setTimeout(function() {
that.dialog = true;
console.log(that.dialog);
}, 2000);
}
}
</script>
try to read this answer from a related issue with calling this inside anonymous functions

Categories