Vue中监听属性watch的求值,以及与computed的适用场景
监听属性
特点:惰性。当值第一次绑定时,不会执行监听函数,只有当值发生改变才会执行。
Vue2的写法
<div id="app">
{{name}}
<div>
const vmWatch = Vue.createApp({
data() {
return{
name: 'summer',
obj: {
title: 'vue3'
}
}
},
watch: {
// 第一次不执行
name(newVal, oldVal) {
console.log(newVal, oldVal)
},
// 立即执行
name: {
handler: function(newVal, oldVal) {
...
},
immediate: true // true 立即执行, false 表示第一次不执行
},
// 深度监听 监听对象内部属性的改变
'obj.title': {
handler: function(newVal, oldVal) {
...
},
deep: true
}
}
}).mount("#app")
Vue3的写法
单个监听
const age = ref(18)
watch(age, (newVal) => {
console.log(newVal)
})
不能直接监听响应式对象
const obj = reactive({
name: 'summer',
age: 18
})
// 报错
watch(obj.age, (newVal)=> {})
// 使用getter函数
watch(() => obj.age, (newVal)=> {
console.log(newVal)
})
深层监听
const obj = reactive({
name: 'summer',
age: 18
})
watch(obj, (newVal, oldVal) => {})
立即执行
// 第一种写法
watch(
source,
(newValue, oldValue) => {
},
// 立即执行
{ immediate: true }
)
// 第二种写法
watchEffect(
source,
(newValue, oldValue) => {
},
)
watch与watchEffect的区别
都能响应式地执行有副作用的回调。主要区别是追踪响应式依赖的方式。
watch 只追踪明确侦听的数据源。仅在数据源改变时才会触发回调。
watchEffect 会在副作用发生期间追踪依赖,它会在同步执行过程中,自动追踪所有能访问到的响应式属性。
仅执行一次
watch(
source,
(newValue, oldValue) => {
},
{ once: true }
)
监听器与计算属性
计算属性computed和监听器watch都可以监听属性的变化,而后处理一些逻辑处理,但是他们都有各自适用的场合。
demo示例代码的对比
<div id="app">{{fullName}}</div>
const vm = Vue.createApp({
data() {
return {
firstName: 'summer',
lastName: 'sunny',
fullName: 'summer sunny'
}
},
watch: {
firstName(val) {
this.fullName = val + ' ' + this.lastName
},
lastName(val) {
this.fullName = this.firstName + ' ' + val
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
}
}
}).mount("#app")
从上面简单的示例代码也可以看出,使用computed属性代码更加清晰,更合理一些。
使用场景:
computed: 当需要基于现有数据计算出新的数据时,简单的同步操作。
watch: 当需要在数据变化时执行异步或者开销较大的操作时。