Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
479 views
in Technique[技术] by (71.8m points)

javascript - VueJS Watcher is not triggered while watching deep object changes

I got a codesandbox that reproduces my problem: codesandbox example watcher not triggering.

I am working on a component that relies on an object with data that can be dynamically added to the object, so for example, in a seperate .js file, I am exporting the following object:

export default {
  defaultSection1: {
    displayName: 'Action',
  },
  defaultSection2: {
    displayName: 'Thriller',
  },
}

I import this object in my component.

I got a debouncer setup from Lodash so that when data changes, it only fires the watcher once after two seconds. The watcher IS triggered perfectly fine for the data that is already in the object (type in the input text box in my example, and the watcher is triggered). But when I dynamically add data to the object, the watcher is not triggered at all. Only when I change routes back and forth, the data is updated, but the watcher is not triggered. Why is this? What can I do so that the watcher is triggered when data is dynamically being added to an object.

methods: {
    fetchAndUpdateData(){
      console.log('Fetching data...')
    },
    addCustomSection(){
      //The watcher should be triggered when this function is called
      const newSectionId = Math.floor(Math.random() * 1000); 
      this.data[newSectionId] = {
         displayName: 'Custom'
      }
    }
  },
  computed: {
    dataWatcher() {
      return this.data;
    },
    updateData() {
      return debounce(this.fetchAndUpdateData, 2000);
    },
  },
  watch: {
    dataWatcher: {
      handler() {
        console.log('Watcher triggered')
        this.updateData();
      },
      deep: true,
    },
  },

Why is the watcher not triggered, when clearly the data is being changed?

Another thing I noticed that is quite strange, is that in Vue 3.0, the watcher IS triggered with exactly the same code.

Codesandbox in Vue 2.6.11, watcher not triggering.

Codesandbox in Vue 3.0, watcher IS triggered with exactly the same code.

question from:https://stackoverflow.com/questions/65935008/vuejs-watcher-is-not-triggered-while-watching-deep-object-changes

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In vue 2 there's reactivity issue when updating an item in an array or a nested field in an object, to solve this you've to use this.$set() method :

this.$set(this.data,newSectionId, {displayName: 'Custom'})

this issue is solved in Vue 3. and you could just do :

  const newSectionId = Math.floor(Math.random() * 1000); 
      this.data[newSectionId] = {
         displayName: 'Custom'
      }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...