详解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中 For, While与递归的用法
May 07 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
Nov 08 Javascript
javascript简单实现图片预加载
Dec 03 Javascript
Javascript基础教程之数组 array
Jan 18 Javascript
Javascript 拖拽的一些高级的应用(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
JavaScript数据库TaffyDB用法实例分析
Jul 27 Javascript
javascript数组去重的六种方法汇总
Aug 16 Javascript
Angular路由简单学习
Dec 26 Javascript
JavaScript实现音乐自动切换和轮播
Nov 05 Javascript
了解ESlint和其相关操作小结
May 21 Javascript
JS解析后台返回的JSON格式数据实例
Aug 06 Javascript
django简单的前后端分离的数据传输实例 axios
May 18 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
IIS下PHP的三种配置方式对比
2014/11/20 PHP
php模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(中)
2017/06/11 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
Javascript miscellanea -display data real time, using window.status
2007/01/09 Javascript
Javascript之文件操作
2007/03/07 Javascript
比较搞笑的js陷阱题
2010/02/07 Javascript
给文字加上着重号的JS代码
2013/11/12 Javascript
Extjs grid添加一个图片状态或者按钮的方法
2014/04/03 Javascript
页面加载完后自动执行一个方法的js代码
2014/09/06 Javascript
Jquery中CSS选择器用法分析
2015/02/10 Javascript
在Mac OS下使用Node.js的简单教程
2015/06/24 Javascript
html+js实现简单的计算器代码(加减乘除)
2016/07/12 Javascript
详解node如何让一个端口同时支持https与http
2017/07/04 Javascript
浅谈Vuejs中nextTick()异步更新队列源码解析
2017/12/31 Javascript
JavaScript实现多重继承的方法分析
2018/01/09 Javascript
vue写一个组件
2018/04/09 Javascript
vue项目webpack中Npm传递参数配置不同域名接口
2018/06/15 Javascript
聊聊Vue中provide/inject的应用详解
2019/11/10 Javascript
react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
2019/11/12 Javascript
vscode 配置vue+vetur+eslint+prettier自动格式化功能
2020/03/23 Javascript
原生小程序封装跑马灯效果
2020/10/21 Javascript
浅谈python中的变量默认是什么类型
2016/09/11 Python
Django实现的自定义访问日志模块示例
2017/06/23 Python
彻彻底底地理解Python中的编码问题
2018/10/15 Python
Python中作用域的深入讲解
2018/12/10 Python
python使用selenium实现批量文件下载
2019/03/11 Python
django写用户登录判定并跳转制定页面的实例
2019/08/21 Python
Python range与enumerate函数区别解析
2020/02/28 Python
Python私有属性私有方法应用实例解析
2020/09/15 Python
瑞士设计师家具和家居饰品网上商店:Bruno Wickart
2019/03/18 全球购物
四年的个人工作自我评价
2013/12/10 职场文书
美容院营销方案
2014/03/05 职场文书
2014县政府领导班子三严三实对照检查材料思想汇报
2014/09/26 职场文书
优秀党员主要事迹范文
2015/11/05 职场文书
react如何快速设置文件路径别名
2021/04/28 Javascript
CSS 伪元素::marker详解
2021/06/26 HTML / CSS