H5W3
当前位置:H5W3 > 其他技术问题 > 正文

Vue中watch使用

虽然Vue.js为我们提供了有用的computed, 但在某些场景下, 仍然还是需要使用到watch.

默认情况下, watch只在被监听的属性值发生变化时执行.

例如:

export default {
data: () => ({
dog: ""
}),
watch: {
dog(newVal, oldVal) {
console.log(`Dog changed: ${newVal}`);
}
}
};
 

如上代码所示, 只有当dog的值有发生改变时, watch中的dog函数才会执行.

watch options

immediate

但是, 在某些情况下, 你可能需要在创建组件后立即运行监听程序.
当然, 你可以将逻辑迁移至methods中, 然后从watchcreated钩子函数中分别调用它, 但有没有更简单一点的办法呢?

你可以在使用watch时, 使用immediate: true选项, 这样它就会在组件创建时立即执行.

export default {
data: () => ({
dog: ""
}),
watch: {
dog: {
handler(newVal, oldVal) {
console.log(`Dog changed: ${newVal}`);
},
immediate: true
}
}
};
 

deep

watch中还有一个属性: deep, 默认值为: false, 即是否需要开启深度监听.
例如:

export default {
data: () => ({
obj: {
hello: 'james'
}
}),
watch: {
obj: {
handler(newVal, oldVal) {
console.log(`obj changed: ${newVal}`);
},
immediate: true,
deep: true
}
}
};
 

deep即深入观察, 监听器会层层遍历, 给对象的所有属性(及子属性)添加监听器. 这样做无疑会有很大的性能开销, 修改obj中任何一个属性都会触发监听器中的处理函数.

若只想监听obj中的某个属性, 可以使用字符串监听形式.

export default {
data: () => ({
obj: {
hello: 'james'
}
}),
watch: {
'obj.hello': {
handler(newVal, oldVal) {
console.log(`obj changed: ${newVal}`);
},
immediate: true,
deep: false
}
}
};
 

动态添加watch

Vue源代码中$watch的实现:

Vue.prototype.$watch = function (
expOrFn,
cb,
options
) {
var vm = this;
if (isPlainObject(cb)) {
return createWatcher(vm, expOrFn, cb, options)
}
options = options || {};
options.user = true;
var watcher = new Watcher(vm, expOrFn, cb, options);
if (options.immediate) {
try {
cb.call(vm, watcher.value);
} catch (error) {
handleError(error, vm, ("callback for immediate watcher "" + (watcher.expression) + """));
}
}
return function unwatchFn () {
watcher.teardown();
}
};
 

基于此, 我们可以将上面的示例代码修改为 动态添加watch, 例如:

export default {
data: () => ({
obj: {
hello: 'james'
}
}),
mounted(){
this.$watch('obj.hello', this.handler, {
immediate: true,
deep: false
})
},
methods: {
handler(newVal, oldVal) {
console.log(`obj changed: ${newVal}`);
}
}
};
 

Warning:
正常情况下, 不推荐使用$watch来动态添加watch, 因为你还需要手动注销watch监听事件

注销watch

若使用动态添加watch, 就需要手动注销了.
从源代码中, 可以看出: this.$watch调用后会有一个返回值, 通过调用此返回值, 即可注销watch.

修改代码如下:

let unWatch = null
export default {
data: () => ({
obj: {
hello: 'james'
}
}),
mounted(){
unWatch = this.$watch('obj.hello', this.handler, {
immediate: true,
deep: false
})
},
methods: {
handler(newVal, oldVal) {
console.log(`obj changed: ${newVal}`);
}
},
beforeMount(){
unWatch()
unWatch = null
}
};
 

本文地址:H5W3 » Vue中watch使用

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址