vue3中的watch和watchEffect差异和使用
有四种类型的监听函数:watch / watchEffect / watchPostEffect / watchSyncEffect。
监听系统两个派别
可以分为两类 watch和watchEffectwatch
watch(监听对象, (旧状态, 新状态) => {
...
})
指定要监听的基本类型、数组等,但必须根据类型更改编写代码。
下一个状态,上一个状态,将传递要监听的值更改前后的值。
下面介绍如何描述受监听数据类型的差异。
(1) 基本类型 ref
const num = ref(0)
watch(num, (next, prev) => {
console.log(next, prev);
})
(2) 数组
const arr = ref([])
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) => {
...
})
【vue3中的watch和watchEffect差异和使用】在这种情况下,只需使用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(() => {
/* ... */
})// later
stop()
清除副作用
当我们组件卸载的时候, 清空监听函数或者定时器需要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 = https://www.it610.com/article/ref(null)
watchEffect(async onInvalidate => {
onInvalidate(() => {
/* ... */
}) // 我们在Promise解析之前注册清除函数
data.value = https://www.it610.com/article/await fetchData(props.id)
})
副作用刷新时机 默认情况下,会在所有的组件 update 前执行:
watchEffect 0
onInvalidate 1
watchEffect 1
onUpdated
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 则是获取
推荐阅读
- ASP.NET|ASP.NET Core中的Razor页面使用视图组件
- vue3和react17(三)|vue3和react17(三) - 生命周期(ts)
- Java|Java 超详细讲解设计模式之中的建造者模式
- python|正则表达式在python中的简单使用(附带例子(正则表达式匹配+数据清洗))
- Vue3+Nuxt3打造SSR网站应用,0到1实现服务端渲染吾爱fen享受
- js高级程序设计|js高级程序设计(第二章)
- JavaScript删除有序数组中的重复项
- Java|Java 超详细讲解设计模式之中的抽象工厂模式
- WebSocket在实时语音识别中的应用
- vue父组件数据更新子组件相关内容未改变问题(用watch解决)