详解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 相关文章推荐
FireFox JavaScript全局Event对象
Jun 14 Javascript
JavaScript Chart 插件整理
Jun 18 Javascript
JS实现将人民币金额转换为大写的示例代码
Feb 13 Javascript
Javascript封装DOMContentLoaded事件实例
Jun 12 Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
Aug 08 Javascript
node.js中的fs.futimesSync方法使用说明
Dec 17 Javascript
返回函数的JavaScript函数
Jun 14 Javascript
JS遍历数组和对象的区别及递归遍历对象、数组、属性的方法详解
Jun 14 Javascript
Bootstrap弹出框modal上层的输入框不能获得焦点问题的解决方法
Dec 13 Javascript
微信小程序实现折叠展开效果
Jul 19 Javascript
JavaScript实现简单轮播图效果
Dec 01 Javascript
jquery实现商品sku多属性选择功能(商品详情页)
Dec 20 jQuery
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
咖啡知识 除了喝咖啡还有那些知识点
2021/03/06 新手入门
Zend公司全球首推PHP认证
2006/10/09 PHP
c#中的实现php中的preg_replace
2009/12/21 PHP
获取php页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
2013/06/03 PHP
PHP 读取大文件的X行到Y行内容的实现代码
2013/06/24 PHP
配置php网页显示各种语法错误
2013/09/23 PHP
php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
2013/09/28 PHP
PHP制作用户注册系统
2015/10/23 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
24款非常有用的 jQuery 插件分享
2011/04/06 Javascript
扩展JavaScript功能的正确方法(译文)
2012/04/12 Javascript
js弹出模式对话框,并接收回传值的方法
2013/03/12 Javascript
jQuery获取注册信息并提示实现代码
2013/04/21 Javascript
AngularJS入门教程之Hello World!
2014/12/06 Javascript
js判断某个方法是否存在实例代码
2015/01/10 Javascript
javascript实现类似java中getClass()得到对象类名的方法
2015/07/27 Javascript
深入浅析NodeJs并发异步的回调处理
2015/12/21 NodeJs
jQuery事件对象总结
2016/10/17 Javascript
jquery拼接ajax 的json和字符串拼接的方法
2017/03/11 Javascript
vue 点击按钮增加一行的方法
2018/09/07 Javascript
利用node 判断打开的是文件 还是 文件夹的实例
2019/06/10 Javascript
selenium+java中用js来完成日期的修改
2019/10/31 Javascript
如何构建 vue-ssr 项目的方法步骤
2020/08/04 Javascript
[02:32]“虐狗”镜头慎点 2016国际邀请赛中国区预选赛现场玩家采访
2016/06/28 DOTA
[03:12]完美世界DOTA2联赛PWL DAY7集锦
2020/11/06 DOTA
Python MySQLdb模块连接操作mysql数据库实例
2015/04/08 Python
Python爬虫爬验证码实现功能详解
2016/04/14 Python
python解压TAR文件至指定文件夹的实例
2019/06/10 Python
python异常处理和日志处理方式
2019/12/24 Python
Python引入多个模块及包的概念过程解析
2020/09/21 Python
html5的新玩法——语音搜索
2013/01/03 HTML / CSS
综合实践活动方案
2014/02/14 职场文书
办公室员工岗位工作职责
2014/03/10 职场文书
在校证明模板
2015/06/17 职场文书
SQL Server的存储过程与触发器以及系统函数和自定义函数
2022/04/10 SQL Server
ubuntu如何搭建vsftpd服务器
2022/12/24 Servers