有四种类型的监听函数:watch / watchEffect / watchPostEffect / watchSyncEffect。
监听系统两个派别
能够分为两类 watch和watchEffect
watch
watch(监听对象, (旧状态, 新状态) => { ...})
指定要监听的根本类型、数组等,但必须依据类型更改编写代码。
下一个状态,上一个状态,将传递要监听的值更改前后的值。
上面介绍如何形容受监听数据类型的差别。
(1) 根本类型 ref
const num = ref(0)watch(num, (next, prev) => { console.log(next, prev);})
(2) 数组
const arr = ref<number[]>([])watch(() => [...arr.value], (next, prev) => { console.log(next, prev);})
(3) 对象
const state = reactive({count : 0, age: 0})watch(() => ({...state}), (next, prev) => { console.log(next, prev);})
监听
数组能够一起传递多个元素,以监听多个元素。然而,有一个注意事项。
如果数组中传递的任何元素产生更改,则watch
将触发,但如果==同时更改,则只触发一次==。
//同时更改const onClick = () => { ++num1.value ++num2.value}// 触发一次watch([num1, num2], (next, prev) => { ...})
在这种状况下,只需应用async await即可触发2次
const onClick = async () => { ++num1.value await nextTick() ++num2.value}watch([num1, num2], (next, prev) => { ...})
监听嵌套对象(deep:true)
const state = reactive({ age: 0, type: { hoge: 0 }})watch(() => state, (next, prev) => { ...}, {deep: true})
组件创立时立刻执行(immidiate:true)
immidiate: true
如果为 true,则在创立组件时也会执行监听函数。
watchEffect
监听
立刻执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时从新运行该函数。
const count = ref(0)watchEffect(() => console.log(count.value))// -> logs 0setTimeout(() => { count.value++ // -> logs 1}, 100)
进行监听
当watchEffect
在组件的setup()
函数或生命周期钩子被调用时,侦听器会被链接到该组件的生命周期,并在组件卸载时主动进行。
在一些状况下,也能够显式调用返回值以进行侦听:
const stop = watchEffect(() => { /* ... */})// laterstop()
革除副作用
当咱们组件卸载的时候, 清空监听函数或者定时器须要onInvalidate
watchEffect(onInvalidate => { const token = performAsyncOperation(id.value) onInvalidate(() => { // id has changed or watcher is stopped. // invalidate previously pending async operation token.cancel() })})
之所以是通过传入一个函数去注册生效回调,而不是从回调返回它,是因为返回值对于异步错误处理很重要。
在执行数据申请时,副作用函数往往是一个异步函数:
const data = ref(null)watchEffect(async onInvalidate => { onInvalidate(() => { /* ... */ }) // 咱们在Promise解析之前注册革除函数 data.value = await fetchData(props.id)})
副作用刷新机会
默认状况下,会在所有的组件 update 前执行:
watchEffect 0onInvalidate 1watchEffect 1onUpdated
watchPostEffect 和 watchSyncEffect
有3种类型:1预(watchEffect)、2 同步(watchSyncEffect)和 3 后(watchPostEffect)。
watchPostEffect 和 watchSyncEffect是watchEffect的第二个参数的==刷新属性==。
watchEffect(() => { //},{ flush: "sync" //or "post" or "pre"})
咱们将具体介绍每个执行工夫。
① pre(watchEffect)
这是默认值。 在组件更新之前异步调用。
也就是说,在生命周期中,它在onBeforeUpdate之前调用
② sync(watchSyncEffect)
在组件更新之前或更新之前,立刻同步调用它。
然而,不倡议同步调用监督成果,因为它效率低下。
通常,它在onBeforeUpdate之前调用。
③ post(watchPostEffect)
在组件更新后调用。 前更新更新到更新的计时。
程序
watchSyncEffect → watchEffect → onBeforeUpdate → watchPostEffect → onUpdated
注意事项
代码程序
watchEffect((onInvalidate) => { console.log("watchEffect", a.value);});let a = ref(0);
下面的代码会执行谬误, 而换成watchPostEffect就不会
异步操作
watchEffect((onInvalidate) => { const b = setTimeout(() => console.log(a.value)); Promise.resolve().then(() => console.log(a.value));});
扭转a的值, 不会触发打印
二者区别
watch 须要侦听==特定的数据源==,能够获取到前后值
watchEffect 则是获取