10

I created a vue object for data reactivity :

let vm = new Vue({
  data () {
    return {
      myData: {}
    }
  },
  watch: {
    myData (value) {
      console.log('changed')
    }
  }
})

When I push / edit / delete into vm.myData, all is ok, the watcher send me changed.

Now, i want to get the changed event only by "touching" vm.myData (without data edition). Can I call an internal method of the observer for this ?

4
  • 2
    What do you even mean by "touching"? Commented Feb 26, 2018 at 9:20
  • Get the watch firen without changing the observed datas. I mean "touch" is used on file systems for only changing metadatas without the content. Commented Feb 26, 2018 at 9:25
  • If you want the logic within your watcher to be fired without changing the data, why not simply abstract it into a method? This way you can call it however you like from your watcher or anywhere else. Commented Feb 26, 2018 at 9:27
  • I show the problem with a dead simple example. In my app i need to notify all my vue components watching a vuex state. I can't add a service between them, this will be overkill. Commented Feb 26, 2018 at 9:33

2 Answers 2

22

Ok I have the solution.

We can trigger the notify() method from the attached observer :

vm.myData.__ob__.dep.notify()

I found it from the source when vuejs patch the original methods in order to put the data reactive.

https://github.com/vuejs/vue/blob/dev/src/core/observer/array.js#L42

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

2 Comments

I wonder why you would ever want to do this in this manner. This all seems like one big code smell to me.
Ok I explain why. I am building a service for Vuex and Laravel Eloquent data sync. When something happens from the backend, data are mutated in frontend, its works fine but the problem is with a cache system : when I know something changes but not really because of the cache (a pages changes), i need to notify readers of the data for refreshing components.
7

since it's an object(object is passed by reference, not by value), it can be done like this

vm.myData = Object.assign({},vm.myData);

this create a new object of the exactly same values, but it's a new object so it will trigger watcher.

https://codepen.io/jacobgoh101/pen/RQeLoM?editors=1011

4 Comments

We will have some "deep copy" problems i think. And will it be fast enough with a large set of datas ? This is not touching, but replacing all the set.
depends on the structure of the object. Object.assign is not deep clone. it only clones the "1st level" property. See Warning for Deep Clone in developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
@Ifnot anyway i don't see other way of touching it. I could delete this answer if it's not what you want
Nah, keep it :) I will benchmark this and test. I am digging into the vue source right now for a visible method on the observer. Thanks for the answer btw.

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.