Vue 组件中 5 种 Watch 形式的应用
解释
watch 是一个对象,这个对象的键是须要察看的 表达式,值能够是间接办法、办法名、蕴含选项的对象等等,Vue 实例会在实例化时调用$watch()
, 遍历 watch 对象的每一个属性,并且察看。
留神,本文不会论述 watch 对象的具体实现源码,只是介绍 watch 对象键值的五种应用形式。
格局:
watch {{ [key: string]: string | Function | Object | Array }
}
应用形式:
-
最间接的,间接用办法作为回调函数(或者说作为值)。
// 咱们用 vue 的 v -model 指令来验证下 watch 对象的性能 <div> <p>{{msg}}</p> <input v-model="msg"> </div>
// pattern1 directly method value watch {// msg1 为表达式,function(oldVal, newVal)为匿名函数,作为回调函数 msg1: function (newVal, oldVal) {console.log("oldVal is:" + oldVal + "newVal is:" + newVal); } }
在双向绑定输入框输出一些值后,看 console 里 watch 对象的成果:
// 初始值为 init,输出 init1 之后的 console 输入 oldVal is: init newVal is: init1
留神,回调函数的第一个参数是新的值,第二个是旧的值。
-
函数名作为值
// 同样用 v -model 验证成果 <div> <p>{{msg2}}</p> <input v-model="msg2"> </div>
// pattern 2 use function name as value watch {msg2: "methodway"} methods: {methodway (newVal, oldVal) {console.log("oldVal is:" + oldVal + "newVal is:" + newVal); } }
console 输入:
// 初始值为 init,输出 init1 之后的 console 输入 oldVal is: init newVal is: init1
-
察看键为对象 / 数组时,须要追加选项deep
当咱们的被观察者是一个 对象 / 数组 的时候,咱们扭转了对象外部属性的值,用通常的 watch 形式是捕获不到的。因为对于数组、对象自身来说,它并没有扭转。这个时候须要加上选项
deep: true
<div> <p>{{msg3.attr1}}</p> <input v-model="msg3.attr1"> </div>
如果应用通常形式,扭转了 msg3 的 attr1 属性值,watch 并不会响应。须要加上 deep 选项:
watch { msg3: {handler: function (newVal, oldVal) {console.log("oldVal is:" + oldVal + "newVal is:" + newVal); }, // 加上这个选项之后,不管被嵌套得多深,被察看的对象的 property 一旦扭转都会响应 deep:true } }
然而在这里的一个输入会有一个问题,尽管你能捕捉到对象的变更,然而你会发现 oldVal 和 newVal 是一样的,console 输入:
// 对象的回调函数种,oldVal 和 newVal 是统一的 oldVal is: {"attr1":"123","attr2":"2"} newVal is: {"attr1":"123","attr2":"2"}
也就是说,尽管咱们能捕捉到变动,然而从 watch 对象外面的回调来说,咱们无奈精确抓取到变动的属性。如果想做到这点,咱们能够独自察看对象的某个属性
msg3.attr1
或者应用computed
做中间层来察看。// computed 做中间层,留神,并不是非要这样多写一层进行察看,能够间接察看属性 computed: {msg3attr() {return this.msg3.attr1;} } watch { msg3attr: function(newVal, oldVal) {console.log("oldVal is:" + oldVal + "newVal is:" + newVal); } }
这样就能察看到属性值的变动:
oldVal is: "12" newVal is: "123"
-
实例化后立即回调
咱们有时候会有要求 Vue 对象实例化后,立即回调某一个 Watch 对象的键值。这个时候只须要加上一个选项
immediate: true
即可<div> <p>{{msg4}}</p> <input v-model="msg4"> </div>
watch { msg4: {handler(newVal, oldVal) {console.log("this should be called immediately."); }, // 加上 immediate 选项后,实例化后立即回调一次 immediate:true }, }
console 输入:
// 留神,咱们并没有扭转 input 的值,实例化之后立即进行了回调 this should be called immediately.
-
回调函数数组
如果咱们有多个回调函数须要执行,咱们能够将 Watch 的值赋值为一个数组,数组内的函数将被逐个调用。
<div> <p>{{msg5}}</p> <input v-model="msg5"> </div>
watch { msg5: [ "methodchain1", function methodchain2(oldVal,newVal) {console.log("second method"); }, {handler(newVal, oldVal) {console.log("third method") },deep:true } ] }, methods: {methodchain1(newVal, oldVal) {console.log("first method"); } }
当 msg5 变更之后,console 的输入:
// 回调函数被逐个调用 first method second method third method
-
值得一提的是,watch 对象中,有时候键能够省略,咱们用键的名字间接用作回调函数的名称,同样能失常察看到表达式的变动。
<div> <p>{{msg}}</p> <input v-model="msg"> </div>
watch { // 间接用表达式作为回调函数名称,成果统一 msg(newVal, oldVal) {console.log("oldVal is:" + oldVal + "newVal is:" + newVal); } }
console 输入:
oldVal is: init newVal is: 1
须要特地留神的是,Watch 对象中的回调函数 不应该 用箭头函数进行定义,它将导致上下文的凌乱,this 将指向谬误的上下文。
以上为回调函数在组件中的五种应用办法,欢送点赞、评论、珍藏。