详解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的caller,callee,call,apply
Apr 28 Javascript
动态样式类封装JS代码
Sep 02 Javascript
JavaScript子窗口ModalDialog中操作父窗口对像
Dec 11 Javascript
关于js二维数组和多维数组的定义声明(详解)
Oct 02 Javascript
Javascript中call,apply,bind方法的详解与总结
Dec 12 Javascript
浅谈express 中间件机制及实现原理
Aug 31 Javascript
JavaScript的Object.defineProperty详解
Jul 09 Javascript
小程序开发基础之view视图容器
Aug 21 Javascript
vuex 解决报错this.$store.commit is not a function的方法
Dec 17 Javascript
vue里的data要用return返回的原因浅析
May 28 Javascript
详解ES6数组方法find()、findIndex()的总结
May 12 Javascript
vant自定义二级菜单操作
Nov 02 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
BBS(php &amp; mysql)完整版(四)
2006/10/09 PHP
Apache2 httpd.conf 中文版
2006/11/17 PHP
Yii2增加验证码步骤详解
2016/04/25 PHP
游戏人文件夹程序 ver 4.03
2006/07/14 Javascript
一步一步教你写一个jQuery的插件教程(Plugin)
2009/09/03 Javascript
JS将数字转换成三位逗号分隔的样式(示例代码)
2014/02/19 Javascript
jquery操作HTML5 的data-*的用法实例分享
2014/08/17 Javascript
jquery 实现两Select 标签项互调示例代码
2014/09/25 Javascript
Jquery实现由下向上展开效果的例子
2014/12/08 Javascript
jQuery中[attribute]选择器用法实例
2014/12/31 Javascript
原生JS实现-星级评分系统的简单实例
2016/08/21 Javascript
vuejs在解析时出现闪烁的原因及防止闪烁的方法
2016/09/19 Javascript
bootstrapValidator bootstrap-select验证不可用的解决办法
2017/01/11 Javascript
AngularJS1.X学习笔记2-数据绑定详解
2017/04/01 Javascript
vue-router实现tab标签页(单页面)详解
2017/10/17 Javascript
详解HTML5 使用video标签实现选择摄像头功能
2017/10/25 Javascript
Vue+Jwt+SpringBoot+Ldap完成登录认证的示例代码
2018/05/21 Javascript
使用javascript做时间倒数读秒功能的实例
2019/01/23 Javascript
利用Bootstrap Multiselect实现下拉框多选功能
2019/04/08 Javascript
基于webpack4+vue-cli3项目实现换肤功能
2019/07/17 Javascript
详解node.js 事件循环
2020/07/22 Javascript
vue3使用vue-count-to组件的实现
2020/12/25 Vue.js
python中pass语句用法实例分析
2015/04/30 Python
基于Python列表解析(列表推导式)
2018/06/23 Python
详解python中*号的用法
2019/10/21 Python
python双端队列原理、实现与使用方法分析
2019/11/27 Python
python 初始化一个定长的数组实例
2019/12/02 Python
python中有函数重载吗
2020/05/28 Python
推荐WEB开发者最佳HTML5和CSS3代码生成器
2015/11/24 HTML / CSS
THE OUTNET英国官网:国际设计师品牌折扣网站
2016/08/14 全球购物
项目合作协议书范本
2014/04/16 职场文书
创建青年文明号材料
2014/05/09 职场文书
国庆节活动总结
2014/08/26 职场文书
个人务虚会发言材料
2014/10/20 职场文书
水电施工员岗位职责
2015/04/11 职场文书
volatile保证可见性及重排序方法
2022/08/05 Java/Android