用例1 – 单值、多值侦听
const value1= ref(1)
const value2 = ref(2)
watchEffect(()=>{
const v = value1.value;
console.log('watchEffect1', v)
})
watchEffect(()=>{
const v = value2.value;
console.log('watchEffect2', v )
})
// 2个值
watchEffect(()=>{
const v2 = value2.value;
const v1 = value1.value;
console.log('2个值', v1,v2)
})
setTimeout(()=>{
value1.value = value2.value
value2.value = value2.value+1
},200)
输出值
// 初始化的时候会执行一次函数
watchEffect1 1
watchEffect2 2
2个值 1 2
// 后续更新的时候会执行watcher
watchEffect1 2
// 多个值侦听会去重,就算2个值发生变化,只会触发一次
2个值 2 3
watchEffect2 3
用例2 – 副作用
// 副作用
const v3 = ref(3)
watchEffect(()=>{
const v = v3.value
// 存在异步
setTimeout(()=>{
console.log(v,'timeout')
},1000);
})
v3.value = 4
v3.value = 5
输出值
// 初始化 收集依赖
3 'timeout'
// 更新数据,异步副作用导致多于数据处理
4 'timeout'
5 'timeout'
主动清除异步
// 副作用
const v3 = ref(3)
watchEffect(async onInvalidate=>{
const v = v3.value
// 存在异步
const timeout = setTimeout(()=>{
console.log(v,'timeout')
},1000);
onInvalidate(()=>{
clearTimeout(timeout)
})
})
v3.value = 4
v3.value = 5
输出值
// 初始化 收集依赖
3 'timeout'
// 重复执行的watcher会触发 onInvalidate,取消上一次的异步请求
5 'timeout'
用例3 – 执行顺序 - pre
// 执行顺序 pre
const v4 = ref(4);
onBeforeUpdate(() => {
console.log('onBeforeUpdate');
});
onUpdated(() => {
console.log('onUpdated');
});
onMounted(() => {
console.log('onMounted');
});
watchEffect(
() => {
const v = v4.value;
console.log('watch 4', v);
},
{
flush: 'pre',
}
);
setTimeout(() => {
v4.value = 1;
}, 1000);
输出值 – 注意:update
与onBeforeUpdate
只有模板引用了值才会触发
watch 4 4
onMounted
watch 4 1
onBeforeUpdate
onUpdated
用例4 – 执行顺序 - post
// 执行顺序 POST
const v4 = ref(4);
onBeforeUpdate(() => {
console.log('onBeforeUpdate');
});
onUpdated(() => {
console.log('onUpdated');
});
onMounted(() => {
console.log('onMounted');
});
watchEffect(
() => {
const v = v4.value;
console.log('watch 4', v);
},
{
flush: 'post',
}
);
setTimeout(() => {
v4.value = 1;
}, 1000);
输出值 – 注意:update
与onBeforeUpdate
只有模板引用了值才会触发
watch 4 4
onMounted
onBeforeUpdate
watch 4 1
onUpdated
用例5 – 执行顺序 - sync
const v3= ref(4);
const v4 = ref(4);
onBeforeUpdate(() => {
console.log('onBeforeUpdate');
});
onUpdated(() => {
console.log('onUpdated');
});
onMounted(() => {
console.log('onMounted');
});
watchEffect(
() => {
const v = v4.value;
console.log('watch 4', v);
v3.value = v
}
);
const v5 = ref(5);
watchEffect(() => {
const v = v5.value;
console.log('watch 5', v);
});
watchEffect(() => {
const v = v3.value;
console.log('watch 3', v);
}, {
flush: 'sync',
});
setTimeout(() => {
v4.value = 1;
v5.value = 1;
}, 1000);
输出值 – 注意:update
与onBeforeUpdate
只有模板引用了值才会触发
watch 4 4
watch 5 5
watch 3 4
onMounted
watch 4 1
watch 3 1
watch 5 1
onBeforeUpdate
onUpdated
我们把v3
修改为其他顺序看看输出是否会发生变化
// ……
watchEffect(
() => {
const v = v3.value;
console.log('watch 3', v);
},
{
flush: 'pre',
}
);
输出值
watch 4 4
watch 5 5
watch 3 4
onMounted
watch 4 1
watch 5 1
watch 3 1
onBeforeUpdate
onUpdated
输出的顺序发生了变化,如果v3
的watchEffect
配置sync,当发生变化的话,就会立马执行,强制效果始终同步触发。
用例6 – 停止侦听
const value1= ref(1)
const stop = watchEffect(()=>{
const v = value1.value;
console.log('watchEffect1', v)
})
stop()
setTimeout(()=>{
value1.value = 2
},200)
输出值
watchEffect1 1