详解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 相关文章推荐
将HTML自动转为JS代码
Jun 26 Javascript
Dojo 学习笔记入门篇 First Dojo Example
Nov 15 Javascript
Jquery绑定事件(bind和live的区别介绍)
Aug 23 Javascript
js实现单行文本向上滚动效果实例代码
Nov 28 Javascript
node.js Web应用框架Express入门指南
May 28 Javascript
使用window.prompt()实现弹出用户输入的对话框
Apr 13 Javascript
Javascript中函数名.length属性用法分析(对比arguments.length)
Sep 16 Javascript
vue实现ajax滚动下拉加载,同时具有loading效果(推荐)
Jan 11 Javascript
VUE前端cookie简单操作
Oct 17 Javascript
swiper在vue项目中loop循环轮播失效的解决方法
Sep 15 Javascript
JS实现碰撞检测效果
Mar 12 Javascript
JS highcharts实现动态曲线代码示例
Oct 16 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 强制性文件下载功能的函数代码(任意文件格式)
2010/05/26 PHP
php算开始时间到过期时间的相隔的天数
2011/01/12 PHP
php从数组中随机抽取一些元素的代码
2012/11/05 PHP
php使用base64加密解密图片示例分享
2014/01/20 PHP
PHP中把对象数组转换成普通数组的方法
2015/07/10 PHP
jquery 表单取值常用代码
2009/12/22 Javascript
jQuery弹出层始终垂直居中相对于屏幕或当前窗口
2013/04/01 Javascript
JavaScript中使用document.write向页面输出内容实例
2014/10/16 Javascript
javascript表格的渲染组件
2015/07/03 Javascript
JavaScript与jQuery实现的闪烁输入效果
2016/02/18 Javascript
jQuery使用Selectator插件实现多选下拉列表过滤框(附源码下载)
2016/04/08 Javascript
基于BootstrapValidator的Form表单验证(24)
2016/12/12 Javascript
详解基于angular-cli配置代理解决跨域请求问题
2017/07/05 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
2017/12/23 Javascript
JS实现前端页面的搜索功能
2018/06/12 Javascript
JS实现图片转换成base64的各种应用场景实例分析
2018/06/22 Javascript
深入理解react-router 路由的实现原理
2018/09/26 Javascript
微信小程序实现单选功能
2018/10/30 Javascript
JavaScript装饰者模式原理与用法实例详解
2020/03/09 Javascript
Python使用MySQLdb for Python操作数据库教程
2014/10/11 Python
Python企业编码生成系统之系统主要函数设计详解
2019/07/26 Python
如何利用Python写个坦克大战
2020/11/18 Python
python如何实现递归转非递归
2021/02/25 Python
css3实现信纸/同学录效果的示例代码
2018/12/11 HTML / CSS
HTML5页面音视频在微信和app下自动播放的实现方法
2016/10/20 HTML / CSS
公共汽车、火车和飞机票的通用在线预订和销售平台:INFOBUS
2019/11/30 全球购物
财务会计专业应届毕业生求职信
2013/10/18 职场文书
2014大学生全国两会学习心得体会
2014/03/13 职场文书
2014年流动人口工作总结
2014/11/26 职场文书
国家助学金感谢信
2015/01/21 职场文书
公司2015年终工作总结
2015/05/26 职场文书
让子弹飞观后感
2015/06/11 职场文书
2016年教师节贺卡寄语
2015/12/04 职场文书
《倍数和因数》教学反思
2016/02/23 职场文书
关于python中readlines函数的参数hint的相关知识总结
2021/06/24 Python
angular异步验证器防抖实例详解
2022/03/31 Javascript