object数组怎么转成int数组(Object.assign触发watch原理示例解析)
为什么可以用Object.assign触发$watch
Object.assign ,这个api在简单拷贝可枚举对象的属性值时经常用到 。这里介绍一个在vue2中Object.assign的用法 ,这个用法在官网文档 有详细介绍:
而且要注意的是如果像下面这样添加上去的新属性无法触发更新:
问题是为什么前面那种写法会有效?
先看vue2文档
在vue2的文档中有详细说明 ,在组件的依赖收集过程中 ,所有property 在被访问和修改时会通知变更 ,对于对象来说 ,Vue 无法检测 property 的添加或移除 。
一般情况下 ,在vue中 ,如果要对data对象中实例添加根级别property ,我们可以这样操作:
或者这样操作
但是如果我们要对一个对象添加多个属性,同时还要保持对象的响应性 ,这种情况下就要用到开篇提到的方法。
在mdn 上 ,对 Object.assign 有这一句解释:该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter 。对这句 ,我们用下面的例子a来理解 。
通过这段代码可以理解上面说的“Object.assign会使用目标对象的[[Set]] ” ,同时 ,这段代码也演示了vue2中响应原理 ,因为vue2中所有需要响应的属性都是用 Object.defineProperty 进行响应绑定 ,这样所有的访问和修改动作都会被追踪到 。
但是对于没有事先被 Object.defineProperty定义的属性 ,比如添加一个属性就无法监听到了 。在上面的示例中 ,即使我用文档提到的用法 obj = Object.assign({},obj, {a: wer23e,c: dfrr23e}) 仍然无法触发c属性的 set 。走到这一步 ,是不是得看watch源码了?其实不必!
用Object.assign触发watch原理
针对这个问题 ,watch的源码不必看 ,但是 Object.assign 的源码必须要看,
其实就是把 assign 方法中的参数的可枚举属性全部复制到此方法的第一参数上去 。回头再去理解下例子a , obj = Object.assign({},obj, {a: wer23e,c: dfrr23e}) 无法触发c属性的 set 函数是因为 ,obj引用关系已经被改变了,不再是原来那个对象 ,也就没有了对应的属性监控 ,但是为什么官方文档会建议这么用呢?
接下来,我写了个小demo ,来帮你理解 ,你可以试下效果
可以看到 ,确实 ,最后一种Object.assign方法会触发test对象监听 。前面两种写法 ,只能触发对象的属性更新响应 ,如果给obj对象添加属性 ,就无法监测到obj的变化 。到这一步 ,其实如果要彻底弄清楚 ,最好还是看下 watch 源码 。我在仔细分析了后,才发现其实跟watch源码没有什么关系 ,所以本文就不展开分析了 ,这是另一篇文章的事了。
如果看不明白 watch 源码也没关系,其实简单解释就是 ,用obj = Object.assign({},obj, {a: wer23e,c: dfrr23e}) 这种方式 ,改变了obj的引用关系,也就是obj的值变了 ,所以如果你在watch函数中监听了obj ,obj是变化了的 ,只不过obj的值是一个 Object 对象而已 ,所以会触发obj对象的响应 。
参考资料:
cn.vuejs.org/v2/guide/re…
developer.mozilla.org/zh-CN/docs/…
https://www.jb51.net/article/265630.htm
https://www.jb51.net/article/266683.htm
以上就是Object.assign触发watch原理示例解析的详细内容 ,更多关于Object.assign触发watch的资料请关注本站其它相关文章!
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!