1

I'm trying to watch the data object with multiple properties using deep invocation, I need to know in the watch call is triggered for which property change in the object. Is there any way to know the property in the handler.

data(){
   return {
        user:{
           first_name:'',
           last_name:'',
            }
    }
},
watch:{
    user:{
       deep:true,
       handler(value){
       //Here I want to know which property(first_name/last_name) change of the user object has triggered this.
        }
    }
}
5
  • probably need to iterate the object and compare the values before and after. Commented Mar 2, 2020 at 14:34
  • @ChrisLi that would be tedious, if the data object is large, I was wondering if there is any way Vue js has provided the property to know. Commented Mar 2, 2020 at 14:35
  • you can also setup watchers programmatically for each key, i don't know if vue provides a method for this. Commented Mar 2, 2020 at 14:36
  • @ChrisLi when I tried to compare the old and new value in the deep watch I found both objects property is updated with the latest values do you have any idea about this. Commented Mar 2, 2020 at 14:51
  • probably because they reference to the same object, here's a work around i found github.com/vuejs/vue/issues/2164#issuecomment-432872718 Commented Mar 2, 2020 at 15:00

2 Answers 2

1

You can do something like this:

<template>
  <div>
    <div>
      <input type="text" v-model="obj.prop1" />
      <input type="text" v-model="obj.prop2" />
      <input type="text" v-model="obj.prop3" />
    </div>
  </div>
</template>

<script>
export default {
  name: 'app',
  data: () => ({
    obj: {
      prop1: '',
      prop2: '',
      prop3: '',
    },
  }),
  mounted() {
    for (const key in this.obj) {
      this.$watch(
        () => this.obj[key],
        (newValue, oldValue) => {
          console.log(key, oldValue, newValue);
        }
      );
    }
  },
};
</script>

With this.$watch method you can create dynamic watchers.

For more details, you can see the documentation: https://v2.vuejs.org/v2/api/#watch

Sign up to request clarification or add additional context in comments.

1 Comment

Did this answer solve your problem? Please accept this answer and this will help others people.
1

It seems vue doesn't have a way to determine what property changed.

Using your example fires watch callback when any property changed.

But vue has one more option:

// keypath
vm.$watch('a.b.c', function (newVal, oldVal) {
  // do something
})

https://v2.vuejs.org/v2/api/#vm-watch

In your case it may be something like this:

data(){
   return {
        user:{
           first_name:'',
           last_name:'',
            }
    }
},
watch:{
    "user.first_name": function(newVal, oldVal) {
      // todo
    },
    "user.last_name": function(newVal, oldVal) {
      // todo
    }
}

But I'm not sure that it's good way

upd from vue documentaion

Note: when mutating (rather than replacing) an Object or an Array, the old value will be the same as new value because they reference the same Object/Array. Vue doesn’t keep a copy of the pre-mutate value.

Manualy compare object is useless in this case because newVal = oldVal (one reference)

upd2: re-creating an object may be warkaround

// for example
user = Object.assign({}, user, { first_name: "newValOfFirstName" })

// instead of
user.first_name = "newValOfFirstName";

3 Comments

@Gurmaks thanks for the answer, I wanted to handle the entire object change in single handler, though I tried to compare object it seems that the Vue is passing both old and new object with the latest value so not able to compare that as well, is it a bug in Vue or I'm doing any wrong.
I forgot about it, sorry. From vue documentation "Note: when mutating (rather than replacing) an Object or an Array, the old value will be the same as new value because they reference the same Object/Array. Vue doesn’t keep a copy of the pre-mutate value.". It means manually compare is useless in this case, because newVal = oldVal. It's one object. I'll update my answer
Or you can re-create object, not mutate

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.