Vue Watch没有触发

Posted

技术标签:

【中文标题】Vue Watch没有触发【英文标题】:Vue Watch not triggering 【发布时间】:2018-03-21 20:46:25 【问题描述】:

尝试使用 vue watch 方法,但即使使用deep:true,它似乎也不会触发某些对象。

在我的组件中,我收到一个数组作为要创建的字段的道具 以下表格。 我可以构建表单并将它们动态绑定到一个名为 crudModelCreate 的对象,一切正常(我在 vue 开发工具中看到,甚至提交表单都按计划工作)

但我在尝试观察该动态对象的变化时遇到了问题。

  <md-input v-for="(field, rowIndex) in fields" :key="field.id" v-model="crudModelCreate[field.name]" maxlength="250"></md-input>

   ...

   data() 
      return 
         state: 1, // This gets changed somewhere in the middle and changes fine
         crudModelCreate: ,
      
   ,
   ...
   watch: 
        'state': 
            handler: function(val, oldVal) 
                this.$emit("changedState", this.state);
                // this works fine
            ,
        ,
        'crudModelCreate': 
            handler: function(val, oldVal) 
                console.log("beep1")
                this.$emit("updatedCreate", this.crudModelCreate);
                // This doesn't work
            ,
            deep: true,
            immediate: true
        ,
    

【问题讨论】:

您的对象的更改是如何执行的? 您可能必须使用Vue.set 来更新对象属性,尤其是在添加新属性时。 Vue.js watching deep properties的可能重复 @SuiDream v-model 对对象进行更改。 @AndreiNemes 绝对正确。在 component.mounted 上,我调用了一个初始化函数,该函数将遍历字段并为 crudModelCreate 变量设置默认值(取决于字段的类型),我通过将 this.crudModelCreate[prop] = value; 更改为 this.$set(this.crudModelCreate, prop, value); 来做到这一点使手表触发。 谢谢@AndreiNemes,Vue.set 是我的答案。 【参考方案1】:

来自文档

由于现代 javascript 的限制(以及 Object.observe 的废弃),Vue 无法检测到属性添加或删除。由于 Vue 在实例初始化期间执行 getter/setter 转换过程,因此数据对象中必须存在一个属性,以便 Vue 对其进行转换并使其具有响应性。

请查看 Reactivity in Depth https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

【讨论】:

即使在初始化值之后通过使用this.$watch('$data.crudModelCreate', this.updated, deep: true ) 之类的方法来添加手表也不太奏效。在做了 Andrei Nemes 所说的之后,它起作用了,所以我想在我的用例中并没有那么大的限制。 实际上文档所说的正是您遇到的问题,当您在 crudModelCreate: 之类的数据上定义一个对象,然后您像在手表 crudModelCreate 那些新道具中一样向它添加一个属性时不会反应,除非您将其分配为Vue.set(object, key, value) 就像@Andrei Nemes 正确提到它并且我从文档中指出的那样 你不知道我一直在寻找这个答案的时间......谢谢!【参考方案2】:

在某些情况下,可以通过将 key 属性添加到包含在 v-model 中传递给它的对象的 json 字符串的子组件来强制刷新。

<Component v-model="deepObject" :key="JSON.stringify(deepObject)" />

【讨论】:

以上是关于Vue Watch没有触发的主要内容,如果未能解决你的问题,请参考以下文章

如何在单文件组件中正确使用 Vue Router beforeRouteEnter 或 Watch 触发方法?

vue中的watch属性

vue中的watch属性

Vue-监听属性

Vue.js watch监视属性

vue2 中 computed 和 watch 的异同