详解vue2 $watch要注意的问题


Posted in Javascript onSeptember 08, 2017

使用$watch监听的时候,监听的数据是一个对象的时候,要注意几点:

监听组件内某个对象里面的某项属性时,不要监听对象,直接监听对象里面的属性(深度监听),只有直接监听这个对象里面的属性,只更新对象里面的属性时也能直接监听到此数组的变化。

data(){
return {
msgs : {
list:[1,2,3]
}
}
},
watch:{
msg(newVal,oldVal){
console.log(newVal);//(1)
},
"msg.list":function(newVal,oldVal){
console.log(newVal)//(2)
}
},
mounted(){
this.$set(this.msg,"list",[1,2,3,4]);//(1)不会打印,(2)会打印
this.$set(this,"msg",{list:[1,2,3,4]}//(1)会打印,(2)会打印
}

数据驱动基于Object.defineProperty()这个功能进行实现,在vue中的数据对象就用树来表示,树的每一个叶子节点都会用Object.defineProperty()来定义get/set方法,而在set方法执行的时候会执行watch方法,实现数据的监听。

我们可以监听树的任一叶子节点,当叶子节点数据发生变化的时候,会执行此叶子节点中监听的方法,同时下级以及下下级甚至更下级的叶子节点的监听方法也会执行(前提是对应的叶子节点数据也有改变).

如下

data(){
 return {
msgs:{
list:[1,2,3],
msg:'1'
}
 }
},
watch:{
msgs(newVal,oldVal){
console.log(newVal);//(1)
},
"msgs.list":function(newVal,oldVal){
console.log(newVal)//(2)
}
"msgs.msg":function(newVal,oldVal){
console.log(newVal)//(3)
}
},
mounted(){
//下面的例子一个一个实验,不要放在一起运行,会造成结果错误。当然也可以自己验证如何放在一起也能验证下面的结果是正确的。

this.$set(this.msgs,"list",[1,2,3,4]);//(1)(3)不会打印,(2)会打印
//分析:这个是更新msgs树中list叶子节点的数据,会触发到 “msgs.list”的监听方法,从而(2)被打印
this.$set(this,"msgs",{list:[1,2,3,5]});//(1)(2)(3)都会打印
//分析:这个是更新msgs中的根节点的数据,会触发“msgs”的监听方法,因根节点下面还有子节点,会继续往下遍历,发现list节点的数据也随之改变,由[1,2,3]=>[1,2,3,4],触发了“msgs.list”的监听方法,同理msg节点的数据从 "1"=>"undefined",也会触发“msgs.msg”的监听方法,所以(1)(2)(3)都会打印。
this.$set(this,"msgs",{list:[1,2,3,4],msg:"1"});//(1)(2)会打印,(3)不会打印
//分析:这个与上面不同的是msg节点的内容并没有改变,一直都是“1”,所以不会触发“msgs.msg”的监听方法,所以(3)没有打印,(1)(2)都会打印
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript更改class和id的方法
Oct 10 Javascript
Javascript 面向对象特性
Dec 28 Javascript
Javascript 面向对象 对象(Object)
May 13 Javascript
Html中JS脚本执行顺序简单举例说明
Jun 19 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
Apr 03 Javascript
JS实现仿微博可关闭弹出层效果
Sep 21 Javascript
onmouseover事件和onmouseout事件全面理解
Aug 15 Javascript
分析JavaScript数组操作难点
Dec 18 Javascript
在JavaScript中实现链式调用的实现
Dec 24 Javascript
支付宝小程序实现省市区三级联动
Jun 21 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
Jul 22 Javascript
element 动态合并表格的步骤
Dec 31 Javascript
Express + Session 实现登录验证功能
Sep 08 #Javascript
Vue中组件之间数据的传递的示例代码
Sep 08 #Javascript
详解jquery插件jquery.viewport.js学习使用方法
Sep 08 #jQuery
JavaScript实现开关等效果
Sep 08 #Javascript
浅谈React Native 中组件的生命周期
Sep 08 #Javascript
Vue仿手机qq的实例代码(demo)
Sep 08 #Javascript
关于Ajax的原理以及代码封装详解
Sep 08 #Javascript
You might like
PHP全概率运算函数(优化版) Webgame开发必备
2011/07/04 PHP
php数组函数序列之array_pop() - 删除数组中的最后一个元素
2011/11/07 PHP
PHP面向对象五大原则之开放-封闭原则(OCP)详解
2018/04/04 PHP
ThinkPHP中图片按比例切割的代码实例
2019/03/08 PHP
php实现快速对二维数组某一列进行组装的方法小结
2019/12/04 PHP
Extjs ajax同步请求时post方式参数发送方式
2009/08/05 Javascript
Mootools 1.2教程 设置和获取样式表属性
2009/09/15 Javascript
解决jquery异步按一定的时间间隔刷新问题
2012/12/10 Javascript
javascript中的__defineGetter__和__defineSetter__介绍
2014/08/15 Javascript
JavaScript获得指定对象大小的方法
2015/07/01 Javascript
jQuery移动端图片上传组件
2016/06/12 Javascript
JS动态加载脚本并执行回调操作
2016/08/24 Javascript
jQuery实现自动调用和触发某个事件的方法
2016/11/18 Javascript
整理关于Bootstrap表单的慕课笔记
2017/03/29 Javascript
关于vue v-for循环解决img标签的src动态绑定问题
2018/09/18 Javascript
JavaScript实现数字前补“0”的五种方法示例
2019/01/03 Javascript
JS禁用右键、禁用Ctrl+u、禁用Ctrl+s、禁用F12的实现代码
2020/12/01 Javascript
微信小程序自定义底部弹出框功能
2020/11/18 Javascript
vuex的使用和简易实现
2021/01/07 Vue.js
[56:41]iG vs Winstrike 2018国际邀请赛小组赛BO2 第二场
2018/08/17 DOTA
python自动化测试之连接几组测试包实例
2014/09/28 Python
python3.5仿微软计算器程序
2020/03/30 Python
python多维数组切片方法
2018/04/13 Python
Python3.6简单的操作Mysql数据库的三个实例
2018/10/17 Python
pygame游戏之旅 添加碰撞效果的方法
2018/11/20 Python
python使用pymongo操作mongo的完整步骤
2019/04/13 Python
html5 实现客户端验证上传文件的大小(简单实例)
2016/05/15 HTML / CSS
Solid & Striped官网:美国泳装品牌
2019/06/19 全球购物
荣耀商城:HIHONOR
2020/11/03 全球购物
毕业自荐书
2013/12/09 职场文书
文明礼仪伴我行演讲稿
2014/05/12 职场文书
结对共建协议书
2014/08/20 职场文书
党员干部群众路线个人整改措施
2014/09/18 职场文书
2014年驾驶员工作总结
2014/11/18 职场文书
教师个人总结范文
2015/02/11 职场文书
2016大学先进团支部事迹材料
2016/03/01 职场文书