详解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开发随笔一 preventDefault的必要
Nov 25 Javascript
javascript中将Object转换为String函数代码 (json str)
Apr 29 Javascript
jQuery链式操作实例分析
Nov 16 Javascript
jquery插件jquery.dragscale.js实现拖拽改变元素大小的方法(附demo源码下载)
Feb 25 Javascript
javascript  数组排序与对象排序的实例
Jul 17 Javascript
js使用formData实现批量上传
Mar 27 Javascript
使用mpvue搭建一个初始小程序及项目配置方法
Dec 03 Javascript
Vue框架下引入ActiveX控件的问题解决
Mar 25 Javascript
jquery 验证用户名是否重复代码实例
May 14 jQuery
vscode中Vue别名路径提示的实现
Jul 31 Javascript
Vue 实现对quill-editor组件中的工具栏添加title
Aug 03 Javascript
Vue 组件注册全解析
Dec 17 Vue.js
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数据库抽象层 PDO
2011/05/07 PHP
PHP两种去掉数组重复值的方法比较
2014/06/19 PHP
Linux环境下php实现给网站截图的方法
2016/05/03 PHP
PHP简单实现上一页下一页功能示例
2016/09/14 PHP
基于Jquery的动态添加控件并取值的实现代码
2010/09/24 Javascript
事件模型在各浏览器中存在差异
2010/10/20 Javascript
juqery 学习之四 筛选查找
2010/11/30 Javascript
当前流行的JavaScript代码风格指南
2014/09/10 Javascript
JS+CSS实现可拖动的弹出提示框
2015/02/16 Javascript
js实现格式化金额,字符,时间的方法
2015/02/26 Javascript
javascript检测移动设备横竖屏
2016/05/21 Javascript
BootStrap智能表单实战系列(十一)级联下拉的支持
2016/06/13 Javascript
jQuery EasyUI Tab 选项卡问题小结
2016/08/16 Javascript
javascript中的面向对象
2017/03/30 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
微信小程序实现锚点定位楼层跳跃的实例
2017/05/18 Javascript
详解JavaScript中typeof与instanceof用法
2018/10/24 Javascript
Vuex 使用 v-model 配合 state的方法
2018/11/13 Javascript
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
2018/12/20 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
使用JS判断页面是首次被加载还是刷新
2019/05/26 Javascript
初试vue-cli使用HBuilderx打包app的坑
2019/07/17 Javascript
JQuery+drag.js上传图片并且实现图片拖曳
2020/11/18 jQuery
Redis使用watch完成秒杀抢购功能的代码
2018/05/07 Python
使用python存储网页上的图片实例
2018/05/22 Python
基于numpy中数组元素的切片复制方法
2018/11/15 Python
详解Django-auth-ldap 配置方法
2018/12/10 Python
Python3分析处理声音数据的例子
2019/08/27 Python
Python enumerate函数遍历数据对象组合过程解析
2019/12/11 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
2020/01/23 Python
Jack Rogers官网:美国经典的女性鞋靴品牌
2019/09/04 全球购物
接口可以包含哪些成员
2012/09/30 面试题
教师校本培训方案
2014/02/26 职场文书
2016形势与政策学习心得体会
2016/01/12 职场文书
MySQL 8.0 驱动与阿里druid版本兼容问题解决
2021/07/01 MySQL
CSS中实现动画效果-附案例
2022/02/28 HTML / CSS