详解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 & DHTML 实例编程(教程)DOM基础和基本API
Jun 02 Javascript
JavaScript实现GriwView单列全选(自写代码)
May 13 Javascript
JavaScript声明变量名的语法规则
Jul 10 Javascript
javascript HTML+CSS实现经典橙色导航菜单
Feb 16 Javascript
关于js二维数组和多维数组的定义声明(详解)
Oct 02 Javascript
angular.fromJson与toJson方法用法示例
May 17 Javascript
JavaScript实现瀑布流图片效果
Jun 30 Javascript
JS实现遍历不规则多维数组的方法
Mar 21 Javascript
JS返回页面时自动回滚到历史浏览位置
Sep 26 Javascript
vue+Vue Router多级侧导航切换路由(页面)的实现代码
Dec 20 Javascript
vue实现分页组件
Jun 16 Javascript
Vue项目中数据的深度监听或对象属性的监听实例
Jul 17 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+swoole对client数据实时更新(一)
2016/01/07 PHP
php判断/计算闰年的方法小结【三种方法】
2019/07/06 PHP
将HTML自动转为JS代码
2006/06/26 Javascript
javascript 写类方式之六
2009/07/05 Javascript
JQuery在光标位置插入内容的实现代码
2010/06/18 Javascript
jquery autocomplete自动完成插件的的使用方法
2010/08/07 Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件
2010/08/24 Javascript
jQuery实现多级下拉菜单jDropMenu的方法
2015/08/28 Javascript
JS JSOP跨域请求实例详解
2016/07/04 Javascript
概述VUE2.0不可忽视的很多变化
2016/09/25 Javascript
JS作用域链详解
2017/06/26 Javascript
vue解决弹出蒙层滑动穿透问题的方法
2018/09/22 Javascript
详解JavaScript中typeof与instanceof用法
2018/10/24 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
vue 组件间的通信之子组件向父组件传值的方式
2020/07/29 Javascript
vue中实现弹出层动画效果的示例代码
2020/09/25 Javascript
Python描述器descriptor详解
2015/02/03 Python
python方向键控制上下左右代码
2018/01/20 Python
利用python如何处理nc数据详解
2018/05/23 Python
从django的中间件直接返回请求的方法
2018/05/30 Python
Python使用百度翻译开发平台实现英文翻译为中文功能示例
2019/08/08 Python
在django模板中实现超链接配置
2019/08/21 Python
python hashlib加密实现代码
2019/10/17 Python
python爬虫添加请求头代码实例
2019/12/28 Python
python实现简单井字棋小游戏
2020/03/05 Python
python用700行代码实现http客户端
2021/01/14 Python
美国珠宝精品店:Opulent Jewelers
2019/08/20 全球购物
Vector, ArrayList, HashTable, HashMap哪些是线程安全的,哪些不是
2015/10/12 面试题
出国签证在职证明
2014/01/16 职场文书
幼儿园义卖活动方案
2014/01/17 职场文书
荷叶圆圆教学反思
2014/02/01 职场文书
教师师德考核自我评价
2014/09/13 职场文书
群众路线教育实践活动对照检查材料
2014/09/22 职场文书
2016年大学迎新工作总结
2015/10/14 职场文书
实用求职信模板范文
2019/05/13 职场文书
JavaScript ES6的函数拓展
2022/01/18 Javascript