watchEffect 使用的注意点
watchEffect(props.data, () => {if(!flag){ msg.value = 'xxx' }})
watchEffect(props.data, async() => {await fn(), msg.value = 'xxx'})
`对于有条件判断或者异步任务的情况下,msg 这个依赖在第一次执行的时候不会被收集到依赖,因为msg需要等到异步函数执行完才会被执行到,但是依赖手机是同步的,内部收集依赖并不会等到异步函数执行完毕- watchEffect 在第一次执行时,会立即开始执行回调函数
- 当遇到 await fn() 时,函数会暂停执行
- 此时 watchEffect 的依赖收集已经完成,但 msg.value 的赋值还没有执行
- 所以 watchEffect 没有收集到 msg 的依赖`
vue3.5 新特性
watch 第二个参数 deep:2, once:true //表示只触发一次!!
这是vue3.5 新提出的一个优化方案,之前只要传递了{deep:true} ,开启对数据的深度监听,无论这个数据的层数是多深,都会持续的监听并且递归收集依赖,这对于性能的损耗是巨大的。 vue3.5 发布了 deep:2 可以传递一个数字,表示递归监听的深度,2 就表示只监听到2层,超过2后,数据的改变是不会触发视图的变化的,因为没有收集依赖。 if条件的好理解,就是第一次不满足条件,无法访问到msg这个依赖。 异步后面的msg,因为在依赖收集的过程中,vue底层不知道这个异步操作到何时结束,所以对于msg的访问会被
const data = ref([
{a:{b:{c:{d:1}}},e:2}
])
watch(data,(newval,oldval) =>{console.log(newVal)}, {deep:2})
onClick() {
data[0].e = 3 // 会触发watch
data[0].a.b.c.d ++
//不会触发watch!!!
}
- props 可以有默认值
const {count = 0, msg="hello world"} = defineProps()
如果传递了props,那么就用传递的值, 否则就是用这里的默认值
watch(count,()=>{}) 这样是会直接报错的
正确的方式
watch(()=>count,() => {}), 必须传递一个函数才可以!!!
- useId() hook
import {useId} from 'vue'
const id = useId()
这个hook 保证每一个vue 实例里面的 id 都是不同的
但是多个vue实例在一个文件里面,不特殊处理就是一样的。
特殊处理:
给每个vue实例配置 prefix 前缀
3.useTemplateRef()
const button = ref()
// 之前的写法,button 必须要跟下面的一直
有了这个useTemplateRef
可以: const buttonRef = useTemplateRef<HTMLButtonElement>('button')
就可以把跟定义数据的ref 给区分开!!!
<el-button ref="button"></el-button>
- onWatcherCleanup()
import {onWatcherCleanup} from 'vue'
用于处理上一次watch监听的所有的副作用函数
const count = ref(0)
const onClick = () => {
count.value++
}
watch(count,(newval)=>{
const handler = () => {
console.log('click', newval)
}
window.addEventListener('click',handler)
// 不清楚上一次的副作用的话,后面每次点击都会触发两次的click事件
onWatcherCleanup(()=> {
removeEventListener('click', handler)
})
}, {immediate:true})
第二种写法:
watch(count,(newval,oldVal, onCleanup)=>{
const handler = () => {
console.log('click', newval)
}
window.addEventListener('click',handler)
// 不清楚上一次的副作用的话,后面每次点击都会触发两次的click事件
onCleanup(()=> {
removeEventListener('click', handler)
})
}, {immediate:true})