VueJS Watcher在观察深度对象变化时不会触发



我得到了一个codesandbox,再现了我的问题:codesandbox示例watcher未触发。

我正在处理一个依赖于对象的组件,该对象具有可以动态添加到对象的数据,因此,例如,在单独的.js文件中,我导出以下对象:

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

我将这个对象导入到我的组件中。

我从Lodash获得了一个debounder设置,以便当数据更改时,它只在两秒钟后触发一次监视器。被触发对于已经存在于对象中的数据来说,这是完美的(在我的示例中,在输入文本框中键入,然后触发监视程序)。但是当我动态地向对象添加数据时,观察器没有被触发在所有。只有当我来回改变路由时,数据才会更新,但不会触发观察者。为什么会这样?当数据被动态地添加到一个对象中时,我该怎么做才能触发监视程序呢?

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,
},
},

当数据明显被更改时,为什么没有触发监视程序?

我注意到的另一件事是很奇怪的,是在Vue 3.0中,观察者被触发与完全相同的代码.

Vue 2.6.11中的代码盒,监视器未触发。

Vue 3.0中的Codesandbox, watcher是用完全相同的代码触发的。

在vue 2有反应性问题时,更新一个项目在一个数组或嵌套字段在一个对象,以解决这个问题,你必须使用this.$set()方法:

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

这个问题在Vue 3中解决了。你可以输入:

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

最新更新