Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vue js watch multiple properties with single handler

Currently I have to watch a few properties. And if each of them changes, I have to invoke the same function:

export default{   // ...... rest of code    watch: {     propa: function(after,before) {       doSomething(after,before);     },     propb: function(after,before) {       doSomething(after,before);     }     // ... so on   } } 

So I am having to write the same code multiple times above. Is it possible to simply have all properties being watched and invoke their change handler without having to write same code multiple times?

PS: I am using vue 1.x

like image 570
rahulserver Avatar asked Mar 11 '17 15:03

rahulserver


People also ask

Can you watch a computed property Vue?

Yes, you can setup watcher on computed property, see the fiddle.

What is vue3 watch?

A watchers provide Vue Js users the ability to produce side effect in reaction to a change in state in one or more reactive variables. Watch are very similar to computed properties as they are both defined as a feature that allows the user to “watch” for a property or data change.

What is the difference between watchers and computed property in Vuejs?

Computed properties are used to calculate the value of a property based on some other conditions. Watchers, on the other hand, are not primarily used for changing the value of a property; instead, they are used to notify you when the value has changed and let you perform certain actions based on these changes.

How do you watch objects in Vue?

Deep watcher over array of objects. vue , we have to import it in the App. vue file and pass users as a prop . In User. vue , we are using watcher over the value which is changing and we are also using user.name property instead of user so that vue can detect the change happening to user.name .


2 Answers

Update: April-2020

For people who are using Vue 3, the watch API can accept multiple sources

import { watch, ref } from 'vue';  export default {   setup(() => {     const a = ref(1), b = ref('hello');      watch([a, b], ([newA, newB], [prevA, prevB]) => {       // do whatever you want     });   }); };  

Original answer for Vue 2

there is no official way to solve your question(see this). but you can use the computed property as a trick:

    export default {       // ...       computed: {         propertyAAndPropertyB() {           return `${this.propertyA}|${this.propertyB}`;         },       },       watch: {         propertyAAndPropertyB(newVal, oldVal) {           const [oldPropertyA, oldProvertyB] = oldVal.split('|');           const [newPropertyA, newProvertyB] = newVal.split('|');           // doSomething         },       },     } 

if you just want to do something and don't care about what's new/old values. ignore two lines

    const [oldPropertyA, oldProvertyB] = oldVal.split('|');     const [newPropertyA, newProvertyB] = newVal.split('|'); 
like image 112
Yi Feng Xie Avatar answered Sep 23 '22 17:09

Yi Feng Xie


Another possibility:

new Vue({    el: '#app',    data: {      name: 'Alice',      surname: 'Smith',      fullName: '' // IRL you would use a computed for this, I'm updating it using a watch just to demo how it'd be used    },    mounted() {      this.$watch(vm => [vm.name, vm.surname], val => {                this.fullName = this.name + ' ' + this.surname;              }, {        immediate: true, // run immediately        deep: true // detects changes inside objects. not needed here, but maybe in other cases      })     }  });
<script src="https://unpkg.com/vue"></script>    <div id="app">    <div>      name:<input v-model="name">    </div>    <div>      surname:<input v-model="surname">    </div>    <div>      full name: {{ fullName }}    </div>  </div>

More info on the Vue API docs for vm.$watch.

like image 28
acdcjunior Avatar answered Sep 23 '22 17:09

acdcjunior