老师关于 computed 和 watch ,我没弄明白,能讲解一下吗
来源:3-11 侦测变化 - watch
小麦弥望
2021-05-11
老师,关于 watch 和 computed 我有些问题,下面是一个简单的demo
<template>
<div></div>
<button @click="change">change</button>
<div>ref1:{{ref1}}</div>
<div>ref2:{{ref2}}</div>
<div>ref3:{{ref3}}</div>
<div>ref4:{{ref4}}</div>
</template>
<script>
import { watch, computed, reactive } from 'vue'
export default {
components: {
},
setup () {
const obj = reactive({
property: 1
})
const change = () => {
obj.property++
console.log(ref1, ref2, ref2.value, ref3, ref4, obj)
}
const ref1 = computed(() => {
return {
property: obj.property
}
})
const ref2 = computed(() => obj)
const ref3 = computed(() => {
return {
property: {
property: obj.property
}
}
})
const ref4 = computed(() => {
return {
property: obj
}
})
watch(ref1, () => {
console.log('监听到了ref1') // 可以被监听
})
watch(ref2, () => {
console.log('监听到了ref2') // 不能被监听
})
watch(ref3, () => {
console.log('监听到了ref3') // 可以被监听
})
watch(ref4, () => {
console.log('监听到了ref4') // 不能被监听
})
watch(ref2.value, () => {
console.log('监听到了ref2.value') // 可以被监听
})
watch(obj, () => {
console.log('监听到了obj') // 可以被监听
})
return {
ref1,
ref2,
ref3,
ref4,
change
}
}
}
</script>
我困惑的是为什么 ref2 和 ref4 不能被watch监听,从demo中看,computed中的写 reactive 的属性的时候就是可以被监听的,直接写reactive就不行,但是这是为什么呢,老师能不能解答一下,或者贴一下相关的链接
我问这个问题的原因是我写了一个组件,使用watch监听一个父组件传入的option,如下所示,
watch(() => props.option, (nextValue, proValue) => {
init()
})
与demo不同的是 这个option结构很复杂,是由很多的响应式对象拼接的,如果可以用 computed处理好,传入组件中统一处理就会很省事了,但是我遇见了demo中的那个问题,我没法确定什么样的 computed 可以被 watch 监听到。从demo中我找到了一些规律,但还是没弄明白为啥会这样,希望老师可以讲解一下
写回答
1回答
-
同学你好 首先 watch 对于 reactive object 在文档中有专门的一章,建议认真阅读,因为还挺有难度的。
https://v3.vuejs.org/guide/reactivity-computed-watchers.html#watching-reactive-objects
再次,回到你的问题,我们能发现这样的规律,当你在 computed 中直接返回 obj 的时候,是不能检测到变化的。
// 比如 const ref2 = computed(() => obj); // 而将 obj 中的某个值展开进行赋值的话,是可以检测到变化的,比如 const ref1 = computed(() => {return {property: obj.property};}); // 中等于使用reactive 上的某一个值返回了一个新的对象。 其实这和上面文档中说的是有关系的,因为当一个 computed 其中的 reactive 是对象的引用, 在对象上面赋值, 对象没有变化,所以就不会有变化了。
012021-05-12
相似问题