vue3的watchEffect监听
最近用vue3很少啦,然后发现有的都忘记了,趁着稍微没有那么忙,写在这记录一下,后面再慢慢补充吧
watchEffect
立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
官方解释:watchEffect接收2个参数
第一个参数就是要运行的副作用函数。这个副作用函数的参数也是一个函数,用来注册清理回调。清理回调会在该副作用下一次执行前被调用,可以用来清理无效的副作用,例如等待中的异步请求 (参见下面的示例)。
第二个参数是一个可选的选项,可以用来调整副作用的刷新时机或调试副作用的依赖。
特点一: 非惰性
<script setup lang='ts'>
import {ref, watchEffect } from 'vue'
// 特征:非惰性========>一进入页面就会立刻自动执行一次
watchEffect(()=> {
console.log("watchEffect")
})
</script>
上面的示例打印会发现,一进入页面就会打印 watchEffect。
特点二: 依赖更改时重新执行
<script setup lang='ts'>
import {ref, watchEffect } from 'vue'
let name = ref<string>('小西瓜')
let age = ref<number>(18)
watchEffect(()=> {
console.log("name监听====>", name) // 只要在其内部使用,就会自动进行监听追踪
})
</script>

副作用函数
副作用函数可以在监听值改变之前做一些事情。
<script setup lang='ts'>
import {ref, watchEffect } from 'vue'
let name = ref<string>('小西瓜')
let age = ref<number>(18)
/**
* @param {function} onCleanup 副作用函数
*/
watchEffect((onCleanup)=> {
console.log("name监听====>", name)
onCleanup(()=> {
console.log('在监听之前可以做一些事情')
})
})
</script>

如何清除副作用
watchEffect
会返回一个函数,只需调用这个函数即可停止监听
<div class="container">
<h1>watchEffect学习</h1>
<div>
<div><label>姓名:</label> <input type="text" v-model="name" placeholder="请输入"></div>
<div><label>年龄:</label> <input type="text" v-model="age" placeholder="请输入"></div>
<button @click="stop">停止监听(清除副作用)</button>
</div>
</div>
/** 清除副作用 */
const stopWatch = watchEffect((onCleanup)=> {
console.log("name监听====>", name)
onCleanup(()=> {
console.log('在监听之前可以做一些事情')
})
})
const stop = ()=> stopWatch() // 点击某个按钮停止监听
</script>
副作用的刷新时机
默认情况下,侦听器将在组件渲染之前执行。设置 flush: 'post'
将会使侦听器延迟到组件渲染之后再执行。
使用场景:比如我们在监听中需要获取某个节点的dom
watchEffect(()=> {
const dom = document.querySelector('#nameDom')
console.log("获取节点:",dom) // null
}, {
flush: 'pre' // 默认是pre
})

解决方法:通过设置flush: 'post,在组件渲染完成后再执行
watchEffect(()=> {
const dom = document.querySelector('#nameDom')
console.log("获取节点:",dom)
}, {
flush: 'post' // 组件渲染完成之后,比如我们需要获取某个节点成功以后再进行其他操作
})

vue也提供给我们一个后置刷新的
watchEffect()
有个更方便的别名watchPostEffect()
,直接👇写就行
watchPostEffect(()=> {
const dom = document.querySelector('#nameDom')
console.log("获取节点:",dom)
})
转载自:https://juejin.cn/post/7246264754141659197