关于vue中的侦听器watch

1. 前言

之前面试遇到过一个问题:
面试官:vue侦听器watch的deep属性了解过吗
我: 没用过
面试官:好吧,那下一题

日常开发确实没用过这个,没办法,一般来说我会的都是项目中用到过的,没用过的不太会单独了解,哎,vue入门太快也不好,很多点容易忽视,今天就研究一下watch中两个我不常用的属性,deepimmediate

二、watch三个属性

通过看api得知watch有三个基本属性,分别是 handlerdeepimmediate

2.1 handler属性

handler就是回调函数,也就是当watch监听的值发生改变的时候调用的回调函数,vue会默认在回调函数填入两个参数,分别是改变后的值和改变前的值
代码类似这样


   
   
<script> export default { data: function() { return { person: "张三", } } watch: { person: { handler: function(newVal, oldVal) { console.log(newVal); }, immediate: false, deep: true }, }, } </script>

通过handler绑定事件执行函数,handler接受一个参数
也可以像这样简写:


   
   
watch:{ name: function(newVal, oldVal){ console.log(newVal); } }

这样就是只绑定了事件处理函数,deepimmediate 均采用默认值
如果想给监听属性绑定多个执行函数, 可以这么写


   
   
watch: { person: [ function(newVal, oldVal){ console.log(newVal); }, { handler: function(newVal, oldVal){ console.log(oldVal); }, deep: true, } ] }

通过这种方式可以为监听属性绑定多个事件处理函数, 这是最常用的一个属性, 借 狂神说java 的一句话:“很多工程师就只会这个handler,你学会剩下deep和immediate属性,就超过了90%的程序员”

2. deep属性

deep属性的默认值为false
举个例子


   
   
data: function(){ return { person: { name: "张三", age: 12 } } }, watch: { person: { handler: function(newVal) { console.log(newVal); }, deep: false } }, methods: { edit: function() { this.person.name = "123" } }

如果给一个按钮绑定点击事件,点击按钮触发edit事件, 那么会不会触发这个侦听器呢?
答案是不会,因为如果这样监听person属性,只有person引用地址发生改变,也就是person整体赋值,才会触发
也就是说edit方法需要这样写才会触发watch


   
   
edit: function(){ this.person = { name: "newName", age: 15 } }

如果将deep属性修改为true,则上述例子结果就不一样,我们将edit代码还原,只修改 person.name 同时将watch中的deep修改为true,当edit方法触发的时候,发现控制台会打印,也就是说watch成功的监听到了person中name属性的改变。
我觉得Vue可能是考虑到性能的问题,如果 deep 属性不是true,没有必要为这个属性的每一个子属性绑定一个侦听器,只有 deep 为true,才会这样做

然而有时候没有必要监听这个person对象的所有属性,可能我们只想监听name属性,那可以这样写


   
   
watch: { "person.name":{ handler: function(newVal, oldVal){ console.log(newVal); } } }

这样可以只监听person对象的name属性

2.3 immediate属性

代表绑定的函数是否立即执行,经过试验,如果 immediate 属性为true, 那么在绑定监听器的时候就会触发,这个过程是在created生命周期之前,应该是在数据劫持的时候完成的(个人猜测,没看过源码)


   
   
<script> export default { name: 'App', data: function() { return { person: { id: 1, name: "张三" }, } }, watch: { person: { handler: function(newVal) { console.log(newVal); }, immediate: true, }, }, created: function(){ console.log(1); } } </script>

最终的结果是handler中的函数先执行,然后才执行created生命周期中的代码

三、注销

发现每一篇博客最后基本都会写注销,我也跟个风(摘自掘金)
组件是经常要被销毁的,平时 watch 都是写在组件的选项中的,他会随着组件的销毁而销毁。
但是,如果我们使用下面这样的方式写 watch,那么就要手动注销了


   
   
const unWatch = app.$watch('text', (newVal, oldVal) => { console.log(`${newVal} : ${oldVal}`); }) unWatch(); // 手动注销watch

vue官网关于实例watch方法解释

image.png

app.$watch调用后会返回一个值,就是unWatch方法(手动销毁)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值