vue.js - 变化检测问题

查看:313
本文介绍了vue.js - 变化检测问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

Vue 不允许在已经创建的实例上动态添加新的根级响应式属性(root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上

是否如上图demo代码示例那样,不能动态添加与a属性同级的新属性,只能将新属性添加到嵌套的对象a里?

PS:页面渲染结果为1 2

解决方案

首先,楼主的结论是正确的,如果尝试在已经创建的实例上动态添加新的根级响应式属性的话,会报如下的错误:

[Vue warn]: Avoid adding reactive properties to a Vue instance or its root $data at runtime - declare it upfront in the data option.


那么,为什么不允许添加新的根级响应式属性?

简单地解读一下,比如我们有以下一个Vue实例,输出到控制台看看结构:

var test = new Vue({
    el: '#app',
    data: {
        a: 'Welcome to your Vue.js app!',
        b: 'http://vuejs.org/guide/'
    }
})

我们可以看到实例下也有a、b属性,而不只是在$data对象里面,为什么?

原因是Vue实例创建时会根据data中的属性进行一系列的初始化操作。举个例子,实例创建时,会在实例上注册对应的ProxyGetter和ProxySetter,在Vue的源码里可以找到这样一段代码:

function proxy (target, sourceKey, key) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  };
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val;
  };
  Object.defineProperty(target, key, sharedPropertyDefinition);
}

这是个什么东西?字面意思,getter代理器和setter代理器呗。a、b属性明明在test.$data对象下,为什么我们能够访问,甚至修改它们?就是ProxyGetter和ProxySetter起的作用。

说到这里,你大概会想到,其实初始化Vue实例时不只做了这么点操作,还有很多很多,都是跟data有关的。那么,如果你添加的是根响应式属性,那么要做的工作几乎和重新初始化一个Vue实例差不多了。。。

这篇关于vue.js - 变化检测问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆