1.watch监听
使用 watch 函数在每次响应式状态发生变化时触发回调函数
-
第一个参数监听源
-
第二个参数回调函数cb(newVal,oldVal)
-
第三个参数一个options配置项是一个对象
- watch 默认是懒执行的:仅当数据源变化时,才会执行回调;可以通过传入
immediate: true
选项来强制侦听器的回调立即执行 - 直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发。要深度监听一个非响应式对象的变化时,可以加上 deep 选项,强制转成深层侦听器
deep: true
- watch 默认是懒执行的:仅当数据源变化时,才会执行回调;可以通过传入
监听一个ref
import {ref,watch,reactive} from 'vue'
const str = ref('123'')
watch(str, (newVal, oldVal) => {
console.log('新的值----', newVal);
console.log('旧的值----', oldVal);
})
监听一个ref深层对象
const obj = reactive({
name:'kathy',
age:25,
adress:{
s:'湖南'
}
}
watch(obj,(newVal,oldVal)=>{
console.log('new----',newVal);
console.log('old---',oldVal);//初始值为undefined,change一次后,newVal,oldVal的值相同,因为对象改变,源对象会跟着改变
},{
immediate:true,//是否立即调用一次
}
)
const change = () =>{
obj.adress.s = '深圳'//不需要deep也会深度监听
}
监听一个普通对象以及同时监听两个两个数据源
const newO = {
sex:{
men:'nam',
age:{
a:23
}
}
}
const str = ref('123')
watch([obj,str],(newVal,oldVal)=>{
console.log('new----',newVal);
console.log('old---',oldVal);
},{
// immediate:true,//是否立即调用一次
deep:true//
}
const change = () =>{
newO.sex.age.a = 33//需要加deep:true监听才会启动
}
2.watchEffect
对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担
watch写法:
const todoId = ref(1)
const data = ref(null)
watch(todoId, async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/todos/${todoId.value}`
)
data.value = await response.json()
}, { immediate: true })
上面可以改写为:
回调会立即执行,不需要指定 immediate: true
watchEffect(async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/todos/${todoId.value}`
)
data.value = await response.json()
})
回调触发时机
停止监听器
- 在 setup() 或 < script setup> 中用同步语句创建的侦听器,会自动绑定到宿主组件实例上,并且会在宿主组件卸载时自动停止
- 如果用异步回调创建一个侦听器,那么它不会绑定到当前组件上,你必须手动停止它,以防内存泄漏
例如:
// ...这个则不会自动停止!
setTimeout(() => {
watchEffect(() => {})
}, 100)
停止侦听器
const unwatch = watchEffect(() => {})
// ...当该侦听器不再需要时
unwatch()