详解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 相关文章推荐
精通Javascript系列之数据类型 字符串
Jun 08 Javascript
javascript两种function的定义介绍及区别说明
May 02 Javascript
使用jquery实现以post打开新窗口
Mar 19 Javascript
浅析基于WEB前端页面的页面内容搜索的实现思路
Jun 10 Javascript
详解JavaScript的表达式与运算符
Nov 30 Javascript
jQuery form 表单验证插件(fieldValue)校验表单
Jan 24 Javascript
关于vue单文件中引用路径的处理方法
Jan 08 Javascript
jquery使用FormData实现异步上传文件
Oct 25 jQuery
Angular6新特性之Angular Material
Dec 28 Javascript
在微信小程序中保存网络图片
Feb 12 Javascript
了解javascript中变量及函数的提升
May 27 Javascript
js实现蒙版效果
Jan 11 Javascript
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
文章推荐系统(三)
2006/10/09 PHP
免费手机号码归属地API查询接口和PHP使用实例分享
2014/04/10 PHP
Laravel Eloquent ORM 多条件查询的例子
2019/10/10 PHP
JavaScript Undefined,Null类型和NaN值区别
2008/10/22 Javascript
使用自定义setTimeout和setInterval使之可以传递参数和对象参数
2009/04/24 Javascript
jquery ui 1.7 ui.tabs 动态添加与关闭(按钮关闭+双击关闭)
2010/04/01 Javascript
JavaScript 用Node.js写Shell脚本[译]
2012/09/20 Javascript
jquery validate在ie8下的bug解决方法
2013/11/13 Javascript
js 操作select与option(示例讲解)
2013/12/20 Javascript
nodejs URL模块操作URL相关方法介绍
2015/03/03 NodeJs
JavaScript实现计算字符串中出现次数最多的字符和出现的次数
2015/03/12 Javascript
文字垂直滚动之javascript代码
2015/07/29 Javascript
基于jQuery实现简单的折叠菜单效果
2015/11/23 Javascript
AngularJS实现的锚点楼层跳转功能示例
2018/01/02 Javascript
AngularJS $http post 传递参数数据的方法
2018/10/09 Javascript
详解ES6 Promise对象then方法链式调用
2018/10/20 Javascript
微信小程序外卖选购页实现切换分类与数量加减功能案例
2019/01/15 Javascript
浅谈Vue.js之初始化el以及数据的绑定说明
2019/11/14 Javascript
vue+vant使用图片预览功能ImagePreview的问题解决
2020/04/10 Javascript
让 python 命令行也可以自动补全
2014/11/30 Python
Python使用MONGODB入门实例
2015/05/11 Python
微信跳一跳python辅助软件思路及图像识别源码解析
2018/01/04 Python
详解Tensorflow数据读取有三种方式(next_batch)
2018/02/01 Python
python如何实现内容写在图片上
2018/03/23 Python
使用python3批量下载rbsp数据的示例代码
2019/12/20 Python
浅析matlab中imadjust函数
2020/02/27 Python
Python控制台实现交互式环境执行
2020/06/09 Python
css3过渡_动力节点Java学院整理
2017/07/11 HTML / CSS
css3.0 图形构成实例练习一
2013/03/19 HTML / CSS
使用before和:after伪类制作css3圆形按钮
2014/04/08 HTML / CSS
阿迪达斯俄罗斯官方商城:adidas俄罗斯
2017/03/08 全球购物
热能动力工程毕业生自荐信
2013/11/07 职场文书
人代会标语
2014/06/30 职场文书
2014年幼儿园后勤工作总结
2014/11/10 职场文书
小学教育见习总结
2015/06/23 职场文书
关于flex 上下文中自动 margin的问题(完整例子)
2021/05/20 HTML / CSS