详解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 相关文章推荐
提高代码性能技巧谈—以创建千行表格为例
Jul 01 Javascript
理解JSON:3分钟课程
Oct 28 Javascript
JS中的public和private对象,即static修饰符
Jan 18 Javascript
JS 两个字符串时间的天数差计算
Aug 25 Javascript
JavaScript原生对象之Date对象的属性和方法详解
Mar 13 Javascript
实例讲解javascript注册事件处理函数
Jan 09 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
Jan 26 Javascript
JavaScript动态添加css样式和script标签
Jul 19 Javascript
关于动态生成dom绑定事件失效的原因及解决方法
Aug 06 Javascript
详解如何使用微信小程序云函数发送短信验证码
Mar 13 Javascript
JavaScript实现Tab选项卡切换
Feb 13 Javascript
Angular8 简单表单验证的实现示例
Jun 03 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
PHP操作MongoDB GridFS 存储文件的详解
2013/06/20 PHP
PHP导航下拉菜单的实现如此简单
2013/09/22 PHP
php实例分享之二维数组排序
2014/05/15 PHP
Laravel 5框架学习之路由、控制器和视图简介
2015/04/07 PHP
PHP通过反射动态加载第三方类和获得类源码的实例
2015/11/27 PHP
Zend Framework教程之Application和Bootstrap用法详解
2016/03/10 PHP
Yii中CGridView禁止列排序的设置方法
2016/07/12 PHP
网页图片延时加载的js代码
2010/04/22 Javascript
得到jQuery detach()后节点中的某个值实现代码
2013/02/05 Javascript
Javascript获取HTML静态页面参数传递值示例
2013/08/18 Javascript
Node.js 异步编程之 Callback介绍(一)
2015/03/30 Javascript
深入浅出讲解ES6的解构
2016/08/03 Javascript
jquery实现折叠菜单效果【推荐】
2017/03/08 Javascript
实现div内部滚动条滚动到底部和顶部的代码
2017/11/15 Javascript
移动web开发之touch事件实例详解
2018/01/17 Javascript
JavaScript变量提升和严格模式实例分析
2019/01/27 Javascript
vue 返回上一页,页面样式错乱的解决
2019/11/14 Javascript
jQuery与原生JavaScript选择HTML元素集合用法对比分析
2019/11/26 jQuery
jQuery开发仿QQ版音乐播放器
2020/07/10 jQuery
js实现跳一跳小游戏
2020/07/31 Javascript
vue cli3.0打包上线静态资源找不到路径的解决操作
2020/08/03 Javascript
[04:49]2014DOTA2国际邀请赛 Newbee顺利挺进总决赛 ImbaTV独家专访
2014/07/19 DOTA
[01:05:40]VG vs Newbee 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
python下载文件记录黑名单的实现代码
2017/10/24 Python
Python+selenium实现截图图片并保存截取的图片
2018/01/05 Python
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
Python实现字符串匹配的KMP算法
2019/04/04 Python
python实现名片管理系统项目
2019/04/26 Python
解决pytorch GPU 计算过程中出现内存耗尽的问题
2019/08/19 Python
Python xlwt模块使用代码实例
2020/06/10 Python
PHP两种查询函数array/row的区别
2013/06/03 面试题
几个判断型的面试题
2012/07/03 面试题
培训心得体会
2013/12/29 职场文书
《燕子专列》教学反思
2014/02/21 职场文书
教堂婚礼主持词
2014/03/14 职场文书
办理房产证委托书
2014/09/18 职场文书