详解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 相关文章推荐
基于json的jquery地区联动效果代码
Jul 06 Javascript
JavaScript插入动态样式实现代码
Feb 22 Javascript
jquery插件制作 表单验证实现代码
Aug 17 Javascript
常用的JS验证和函数汇总
Dec 23 Javascript
jQuery选择器及jquery案例详解(必看)
May 20 Javascript
BootStrap 下拉菜单点击之后不会出现下拉菜单(下拉菜单不弹出)的解决方案
Dec 14 Javascript
ES6中module模块化开发实例浅析
Apr 06 Javascript
JS仿QQ好友列表展开、收缩功能(第一篇)
Jul 07 Javascript
element-ui上传一张图片后隐藏上传按钮功能
May 22 Javascript
微信小程序 动态修改页面数据及参数传递过程详解
Sep 27 Javascript
JS严格模式原理与用法实例分析
Apr 27 Javascript
详解JavaScript执行模型
Nov 16 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中设置index.php文件为只读的方法
2013/02/06 PHP
Zend的MVC机制使用分析(一)
2013/05/02 PHP
XAMPP安装与使用方法详细解析
2013/11/27 PHP
PHP弹出对话框技巧详细解读
2015/09/26 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
jquery中dom操作和事件的实例学习 仿yahoo邮箱登录框的提示效果
2011/11/30 Javascript
firefox下jQuery UI Autocomplete 1.8.*中文输入修正方法
2012/09/19 Javascript
jquery实现更改表格行顺序示例
2014/04/30 Javascript
javascript中通过arguments参数伪装方法重载
2014/10/08 Javascript
JavaScript前补零操作实例
2015/03/11 Javascript
Angular.js项目中使用gulp实现自动化构建以及压缩打包详解
2017/07/19 Javascript
JavaScript对象拷贝与Object.assign用法实例分析
2018/06/20 Javascript
webuploader实现上传图片到服务器功能
2018/08/16 Javascript
探索JavaScript中私有成员的相关知识
2019/06/13 Javascript
p5.js临摹旋转爱心
2019/10/23 Javascript
layUI的验证码功能及校验实例
2019/10/25 Javascript
JavaScript修改注册表实例代码
2020/01/05 Javascript
jquery实现垂直手风琴菜单
2020/03/04 jQuery
微信小程序自定义联系人弹窗
2020/05/26 Javascript
Vue触发input选取文件点击事件操作
2020/08/07 Javascript
vue-cli3配置favicon.ico和title的流程
2020/10/27 Javascript
Vue 3自定义指令开发的相关总结
2021/01/29 Vue.js
[42:39]老党炸弹人试玩视频
2014/09/03 DOTA
python中日期和时间格式化输出的方法小结
2015/03/19 Python
centos6.4下python3.6.1安装教程
2017/07/21 Python
Python中的defaultdict与__missing__()使用介绍
2018/02/03 Python
Linux下多个Python版本安装教程
2018/08/15 Python
Pytorch通过保存为ONNX模型转TensorRT5的实现
2020/05/25 Python
美国在线家具网站:GDFStudio
2021/03/13 全球购物
Kappa英国官方在线商店:服装和运动器材
2020/11/22 全球购物
servlet面试题
2012/08/20 面试题
会计系毕业个人自荐信格式
2013/09/23 职场文书
董事长秘书职责
2014/01/31 职场文书
公司出纳岗位职责
2015/03/31 职场文书
2015年政教主任工作总结
2015/07/23 职场文书
vue使用v-model进行跨组件绑定的基本实现方法
2021/04/28 Vue.js