watchEffect
接受一个函数,当依赖改变时,重新调用该函数。
const count = ref(0) watchEffect(() => console.log(count.value)) setTimeout(() => { count.value++ }, 100)
当watchEffect()
在setup()或生命周期钩子中被调用时,监听就始终存在该组件的生命周期中,直到组件unmount
.
另一种卸载监听的情况是,watchEffect()返回一个stop handler
,调用该handler即可停止监听。
const stop = watchEffect(() => { /* ... */ }) // later stop()
当向后台获取数据时,watchEffect()接受async
回调函数。
const data = ref(null) watchEffect(async () => { data.value = await fetchData(props.id) })
组件的update
函数也有watch effect
。用户定义的watchEffect会在组件update之后再去调用。
<template> <div>{{ count }}</div> </template> <script> export default { setup() { const count = ref(0) watchEffect(() => { console.log(count.value) }) return { count } } } </script>
上述代码,第一轮会同步打印count.value(在onmount
生命周期前); 当count发生改变时,先执行组件更新,然后再去log.
如果想将watchEffect中的回调函数第一次执行,放在onmount后,
onMounted(() => { watchEffect(() => { // access the DOM or template refs }) })
如果想让watchEffect()调用发生在组件update
前,或re-run同步,需要传递一个带有flush属性(默认值为post)的option对象。
watchEffect(()=> { //... }, { flush: 'sync' // 在更新前触发 flush: "pre" })
此外,option对象还有ontrack和ontrigger两个函数属性,用于调试watcher的行为。
- onTrack will be called when a reactive property or ref is tracked as a dependency
- onTrigger will be called when the watcher callback is triggered by the mutation of a dependency
watchEffect( () => { /* side effect */ }, { onTrigger(e) { debugger // 进行交互式调试 } } )
watch
等价于vue 2.x中的this.$watch.
相比于watchEffect(), watch()可帮我们实现:
- Perform the side effect lazily;
- Be more specific about what state should trigger the watcher to re-run;
- Access both the previous and current value of the watched state.
watch()的数据源可以是一个返回值的getter
函数,或者是一个ref
对象。
// watching a getter const state = reactive({ count: 0 }) watch( () => state.count, (count, prevCount) => { /* ... */ } ) // directly watching a ref const count = ref(0) watch(count, (count, prevCount) => { /* ... */ })
对于多数据源的监听,可借助数组。
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => { /* ... */ })
生命周期钩子
可以使用直接导入的onXXX
功能注册生命周期钩子:
import { onMounted, onUpdated, onUnmounted } from 'vue' const MyComponent = { setup() { onMounted(() => { console.log('mounted!') }) onUpdated(() => { console.log('updated!') }) onUnmounted(() => { console.log('unmounted!') }) } }
这些生命周期钩子注册功能只能在期间同步使用setup()
(只能在setup()中调用),因为它们依赖于内部全局状态来定位当前活动实例(当前setup()正在被调用的组件实例)。在没有当前活动实例的情况下调用它们将导致错误。
2.x生命周期选项和3.0Composition API之间的映射
- beforeCreate -> 使用 setup()
- created -> 使用 setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
新钩子
除了2.x生命周期等效项之外,3.0Composition API还提供了以下调试挂钩:
- onRenderTracked
- onRenderTriggered
两个钩子都收到DebuggerEvent类似于onTrack
和onTrigger
观察者的选项:
export default { onRenderTriggered(e) { debugger // inspect which dependency is causing the component to re-render } }