划重点:用户创建的侦听器回调,都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。如果想在侦听器回调中能访问被 Vue 更新之后的 DOM,你需要指明 flush: ‘post’ 选项:
1.watch
- 及时回调 添加:immediate: true
- 深度监听 添加:deep:true
用法:
...
const test = ref(0)
const test2 = reactive({id:1,name:'Jack'...})
const test3 = ref({id:1,name:'Jack'...})
// 监听一个普通类型或一个对象
watch(test,(newVal,oldVal)=>{...
})
watch(test2 ,(newVal,oldVal)=>{...
})
// 当是用ref声明的一个对象时,去监听整个对象 监听不到
watch(test3 ,(newVal,oldVal)=>{... // 无法监听到对象下对象的变化
})
// 监听对象的当个属性
watch(()=>test2.name,(newVal,oldVal)=>{...
})
// 监听对象的多个属性
watch(()=>[test2.id,test2.name],(newIdVal,newNameVal,oldIdVal,oldNameVal)=>{...
})
2.wathcEffect
- 立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
- watch 和 watchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
用法:
watch(todoId, async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
}, { immediate: true })// 侦听器两次使用 todoId 的,一次是作为源,另一次是在回调中。以上例子改写为watchEffect
watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
})
3.watchPostEffect
- watchEffect() 使用 flush: ‘post’ 选项时的别名。
- 在侦听器回调中能访问被 Vue 更新之后的 DOM
watchPostEffect(()=>{})
// 等同于
watchEffect(() => {...}, {flush: 'post',}
)
4.watchSyncEffect
- watchEffect() 使用 flush: ‘sync’ 选项时的别名。
- 在某些特殊情况下 (例如要使缓存失效),可能有必要在响应式依赖发生改变时立即触发侦听器
watchSyncEffect(()=>{})
// 等同于
watchEffect(() => {...}, {flush: 'sync',}
)
5. 停止监听器
在 setup() 或 中用同步语句创建的侦听器,会自动绑定到宿主组件实例上,并且会在宿主组件卸载时自动停止。前提是侦听器必须用同步语句创建:如果用异步回调创建一个侦听器,那么它不会绑定到当前组件上,你必须手动停止它,以防内存泄漏
...
// 它会自动停止
watchEffect(() => {})// ...这个则不会!
const stop =setTimeout(() => {watchEffect(() => {})
}, 100)//要手动停止一个侦听器,请调用 watch 或 watchEffect 返回的函数:
beforeUnmount(()=>{
stop()
)
...