Vue.js实例创建后如何动态添加可被监听的响应式数据元素?
问题解决方案
这个问题本质是Vue不同版本响应式实现的固有特性限制,对应解决方案如下:
Vue 2.x 版本
Vue 2 基于 Object.defineProperty 实现响应式,只有初始化时预先声明在data中的属性才会被做响应式劫持,后续动态新增的属性默认不具备响应能力,可通过以下API解决:
- 单个新增属性:使用实例方法
$set或者全局方法Vue.set即可给指定对象新增响应式属性,完全匹配你期望的watch_new_variable用法
// 给根data新增响应式属性 this.$set(this.$data, 'new_object', { test_key: 'test_value' }) // 给已存在的嵌套对象新增响应式属性 this.$set(this.some_object, 'new_key', 100)
- 批量新增属性:不需要逐个调用
$set,直接生成新对象替换原有对象即可触发响应
// 批量给some_object新增多个属性 this.some_object = Object.assign({}, this.some_object, { key1: 'value1', key2: 'value2', key3: 'value3' })
- 动态场景最优实践:如果需要大量新增根级别属性,不需要反复修改初始data结构,只要提前在初始data中预留一个空的动态属性容器即可
// 初始data预先声明动态属性容器 var data = { some_string: "hello", some_object: { whatever: 10 }, // 所有动态新增的属性都挂载到该容器下 dynamic_vars: {} } // 后续新增动态变量不需要修改根data this.$set(this.dynamic_vars, 'new_object', { a: 1 }) // 批量更新直接替换整个容器即可 this.dynamic_vars = { ...this.dynamic_vars, var1: 'a', var2: 'b' }
Vue 3.x 版本
Vue 3 基于 Proxy 实现响应式,天然支持监听对象的动态新增、删除属性操作,不需要调用额外API,直接赋值即可触发响应:
// 直接新增根级别属性即可正常响应 this.new_object = { test_key: 'test_value' } // 直接给已有嵌套对象新增属性也可正常响应 this.some_object.new_key = 100
内容的提问来源于stack exchange,提问作者Darren Oakey
相关产品推荐
相关产品推荐

