详解Vue中watch的高级用法


Posted in Javascript onMay 02, 2018

假设有如下代码:

<div>
   <p>FullName: {{fullName}}</p>
   <p>FirstName: <input type="text" v-model="firstName"></p>
</div>

new Vue({
 el: '#root',
 data: {
  firstName: 'Dawei',
  lastName: 'Lou',
  fullName: ''
 },
 watch: {
  firstName(newName, oldName) {
   this.fullName = newName + ' ' + this.lastName;
  }
 } 
})

上面的代码的效果是,当我们输入firstName后,wacth监听每次修改变化的新值,然后计算输出fullName。

handler方法和immediate属性

这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 firstName 改变时才执行监听计算。那我们想要一开始就让他最初绑定的时候就执行改怎么办呢?我们需要修改一下我们的 watch 写法,修改过后的 watch 代码如下:

watch: {
 firstName: {
  handler(newName, oldName) {
   this.fullName = newName + ' ' + this.lastName;
  },
  // 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
  immediate: true
 }
}

注意到handler了吗,我们给 firstName 绑定了一个handler方法,之前我们写的 watch 方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler。

而immediate:true代表如果在 wacth 里声明了 firstName 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。

deep属性

watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听,比如我们 data 里有一个obj属性:

<div>
   <p>obj.a: {{obj.a}}</p>
   <p>obj.a: <input type="text" v-model="obj.a"></p>
</div>

new Vue({
 el: '#root',
 data: {
  obj: {
   a: 123
  }
 },
 watch: {
  obj: {
   handler(newName, oldName) {
     console.log('obj.a changed');
   },
   immediate: true
  }
 } 
})

当我们在在输入框中输入数据视图改变obj.a的值时,我们发现是无效的。受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

默认情况下 handler 只监听obj这个属性它的引用的变化,我们只有给obj赋值的时候它才会监听到,比如我们在 mounted事件钩子函数中对obj进行重新赋值:

mounted: {
 this.obj = {
  a: '456'
 }
}

这样我们的 handler 才会执行,打印obj.a changed。

相反,如果我们需要监听obj里的属性a的值呢?这时候deep属性就派上用场了!

watch: {
 obj: {
  handler(newName, oldName) {
   console.log('obj.a changed');
  },
  immediate: true,
  deep: true
 }
}

deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。

优化,我们可以是使用字符串形式监听。

watch: {
 'obj.a': {
  handler(newName, oldName) {
   console.log('obj.a changed');
  },
  immediate: true,
  // deep: true
 }
}

这样Vue.js才会一层一层解析下去,直到遇到属性a,然后才给a设置监听函数。

Javascript 相关文章推荐
两种简单实现菜单高亮显示的JS类代码
Jun 27 Javascript
JsDom 编程小结
Aug 09 Javascript
js动态添加onclick事件可传参数与不传参数
Jul 29 Javascript
jquery实现鼠标滑过小图时显示大图的方法
Jan 14 Javascript
细数JavaScript 一个等号,两个等号,三个等号的区别
Oct 09 Javascript
jquery网页日历显示控件calendar3.1使用详解
Nov 24 Javascript
jQuery实现文档树效果
Feb 20 Javascript
AngularJS使用ng-class动态增减class样式的方法示例
May 18 Javascript
javascript实现Java中的Map对象功能的实例详解
Aug 21 Javascript
webpack热模块替换(HMR)/热更新的方法
Apr 05 Javascript
jQuery中$原理实例分析
Aug 13 jQuery
jQuery实现图片下载代码
Jul 18 jQuery
Vue.js中关于侦听器(watch)的高级用法示例
May 02 #Javascript
Vue SSR 组件加载问题
May 02 #Javascript
基于jquery实现左右上下移动效果
May 02 #jQuery
关于Vue在ie10下空白页的debug小结
May 02 #Javascript
解析Json字符串的三种方法日常常用
May 02 #Javascript
使用vue-cli创建项目的图文教程(新手入门篇)
May 02 #Javascript
vue中的模态对话框组件实现过程
May 01 #Javascript
You might like
php中解析带中文字符的url函数分享
2015/01/20 PHP
php socket通信(tcp/udp)实例分析
2016/02/14 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
PHP文件类型检查及fileinfo模块安装使用详解
2019/05/09 PHP
Javascript typeof 用法
2008/12/28 Javascript
jQuery UI Autocomplete 体验分享
2012/02/14 Javascript
如何用js控制frame的隐藏或显示的解决办法
2013/03/20 Javascript
javascript不同类型数据之间的运算的转换方法
2014/02/13 Javascript
网页禁用右键菜单和鼠标拖动选择方法小结
2015/02/25 Javascript
jQuery实现360°全景拖动展示
2015/03/18 Javascript
浅谈javascript中call()、apply()、bind()的用法
2015/04/20 Javascript
javascript关于继承解析
2016/05/10 Javascript
jQuery 利用$.ajax 时获取原生XMLHttpRequest 对象的方法
2016/08/25 Javascript
基于jQuery实现的幻灯图片切换
2016/12/02 Javascript
JavaScript函数节流和函数防抖之间的区别
2017/02/15 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
2018/09/29 Javascript
聊聊Vue中provide/inject的应用详解
2019/11/10 Javascript
如何利用 JS 脚本实现网页全自动秒杀抢购功能
2020/10/12 Javascript
Python 检查数组元素是否存在类似PHP isset()方法
2014/10/14 Python
Python bsddb模块操作Berkeley DB数据库介绍
2015/04/08 Python
python处理Excel xlrd的简单使用
2017/09/12 Python
Python编写合并字典并实现敏感目录的小脚本
2019/02/26 Python
python列表插入append(), extend(), insert()用法详解
2019/09/14 Python
Python+numpy实现矩阵的行列扩展方式
2019/11/29 Python
利用PyCharm操作Github(仓库新建、更新,代码回滚)
2019/12/18 Python
浅谈pandas.cut与pandas.qcut的使用方法及区别
2020/03/03 Python
python实现简单井字棋游戏
2020/03/04 Python
python 获取当前目录下的文件目录和文件名实例代码详解
2020/03/10 Python
俄罗斯在线购买飞机票、火车票、巴士票网站:Tutu.ru
2020/03/16 全球购物
Servlet都有哪些方法?主要作用是什么?
2014/03/04 面试题
行政经理的岗位职责
2013/11/23 职场文书
特色冷饮店创业计划书
2014/01/28 职场文书
党员学习中共十八大思想报告
2014/09/12 职场文书
白银帝国观后感
2015/06/17 职场文书
关于SpringBoot 使用 Redis 分布式锁解决并发问题
2021/11/17 Redis
MySQL窗口函数的具体使用
2021/11/17 MySQL