计算属性允许我们声明性的计算衍生值,然而在某些情况下,我们需要在状态变化的时候执行一些副作用,例如更改DOM,或者根据异步操作去修改另一处的状态。
watch的第一个参数可以是不同形式的"数据源",它可以是一个
1、ref(包括计算属性)
2、一个响应式对象
3、一个getter函数
4、多个数据源组成的求组
下面分别对应的讲解一下
基本类型
const message = ref(1)
// 1 直接检测,返回新旧值
watch(message, (newVal, oldVal)=>{
console.log(newVal, oldVal)
})
// 2 检测返回的getter函数,返回新旧值
watch(()=>message.value, (newVal, oldVal)=>{
console.log(newVal, oldVal)
})
引用类型
const message = ref({ count: 0})
// 1直接检测,新旧值相等(注意这里需要加deep)
watch(message, (newVal, oldVal)=>{
console.log(newVal, oldVal)
}, {deep: true})
// 2 检测到具体属性返回的getter函数,返回新旧值
watch(()=>message.value.count, (newVal,oldVal)=>{
console.log(newVal, oldVal)
})
// 3 不可用,报警告
// watch(message.value.count, ()=>{})
// 4 不可用,没输出
// watch(()=>message, ()=>{})
const message = reactive({ count: 0})
// 1直接检测,新旧值相等
watch(message, (newVal, oldVal)=>{
console.log(newVal, oldVal)
})
// 2 检测到具体属性返回的getter函数,返回新旧值
watch(()=>message.count, (newVal,oldVal)=>{
console.log(newVal, oldVal)
})
// 3 不可用,报警告
// watch(message.count, ()=>{})
// 4 不可用,没输出
// watch(()=>message, ()=>{})
每一个类型对应的getter写法都在1,2,4已经写了,不在单独罗列
const messagea = ref(1)
const messageb = ref(2)
// 1 直接监测,返回值是数组每一项对应的最新值
watch([messagea, messageb], ([newX, newY]) =>{
console.log(newX, newY)
})
// 2 getter监测返回值,返回值是数组每一项对应的最新值
watch([messagea, ()=>message.value], ([newX, newY]) =>{
console.log(newX, newY)
})
总结起来:
1、基本类型-支持任何写法,且返回值都是新旧值(reactive没有基本类型,只有ref有)
2、引用类型-监测具体属性的getter返回值的写法,无论是ref还是reactive,返回值都是新旧值
3、引用类型-监测本身,无论是ref还是reactive,返回的新旧值相等,需要注意ref监测本身时需要添加deep
2和3的引用类型简单来说,无论是reg还是reactive,要么通过具体属性getter返回值的写法检测(返回新旧值),要么是通过直接检测本身(返回相同的值)
watch中的立即执行immediate和deep以及flush属性,比较简单,不再举例说明,可以看官网