详解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 相关文章推荐
UserData用法总结 lanyu出品
Jul 01 Javascript
Javascript实现DIV滚动自动滚动到底部的代码
Mar 01 Javascript
js indexOf()定义和用法
Oct 21 Javascript
javascripit实现密码强度检测代码分享
Dec 12 Javascript
深入理解JS中的变量及作用域、undefined与null
Mar 04 Javascript
深入理解JavaScript系列(34):设计模式之命令模式详解
Mar 03 Javascript
jQuery替换textarea中换行的方法
Jun 10 Javascript
js调用百度地图及调用百度地图的搜索功能
Sep 07 Javascript
javascript入门之string对象【新手必看】
Nov 22 Javascript
Angular.js中处理页面闪烁的方法详解
Mar 09 Javascript
jQuery插件DataTables分页开发心得体会
Aug 22 jQuery
json.stringify()与json.parse()的区别以及用处
Jan 25 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中使用BigMap实例
2015/03/30 PHP
PHP获取redis里不存在的6位随机数应用示例【设置24小时过时】
2017/06/07 PHP
PHP的JSON封装、转变及输出操作示例
2019/09/27 PHP
js获取height和width的方法说明
2013/01/06 Javascript
jQuery Animation实现CSS3动画示例介绍
2013/08/14 Javascript
Jquery如何实现点击时高亮显示代码
2014/01/22 Javascript
js实现九宫格图片半透明渐显特效的方法
2015/02/16 Javascript
JavaScript使用replace函数替换字符串的方法
2015/04/06 Javascript
Nodejs实现批量下载妹纸图
2015/05/28 NodeJs
javascript中的previousSibling和nextSibling的正确用法
2015/09/16 Javascript
详解JavaScript的流程控制语句
2015/11/30 Javascript
jQuery对象的链式操作用法分析
2016/05/10 Javascript
Bootstrap下拉菜单效果实例代码分享
2016/06/30 Javascript
jquery.Jcrop结合JAVA后台实现图片裁剪上传实例
2016/11/05 Javascript
Vue.js计算属性computed与watch(5)
2016/12/09 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
2017/03/04 Javascript
原生js实现瀑布流布局
2017/03/08 Javascript
Nodejs读取文件时相对路径的正确写法(使用fs模块)
2017/04/27 NodeJs
实例详解JavaScript中setTimeout函数的执行顺序
2017/07/12 Javascript
三种Webpack打包方式(小结)
2018/09/19 Javascript
JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解
2018/12/12 Javascript
vue keep-alive列表页缓存 详情页返回上一页不刷新,定位到之前位置
2019/11/26 Javascript
JS window对象简单操作完整示例
2020/01/14 Javascript
Python+matplotlib绘制不同大小和颜色散点图实例
2018/01/19 Python
让代码变得更易维护的7个Python库
2018/10/09 Python
python实现微信自动回复机器人功能
2019/07/11 Python
Django框架 信号调度原理解析
2019/09/04 Python
Django 构建模板form表单的两种方法
2020/06/14 Python
HTML5如何为形状图上颜色怎么绘制具有颜色和透明度的矩形
2014/06/23 HTML / CSS
介绍一下mysql的日期和时间函数
2013/03/28 面试题
高一数学教学反思
2014/02/07 职场文书
狮子林导游词
2015/02/03 职场文书
2015年医院工作总结范文
2015/04/09 职场文书
php去除数组中为0的元素的实例分析
2021/11/17 PHP
68行Python代码实现带难度升级的贪吃蛇
2022/01/18 Python
JS实现简单的九宫格抽奖
2022/06/28 Javascript