Vue3 之 ref、shallowRef、customRef
-
ref 把对象转化为响应式的;
-
shallowRef是浅层响应式数据,即:只有对value整体修改,才能更新到视图层。而修改具体属性值时,不会更新视图。(shallowReactive和shallowRef一样的效果);
-
shallowRef() 存在的意义:将最终的结果输出到视图,节省一些不必要的输出;
-
shallowRef() 对属性值的修改是可以的,只是不更新到视图层;
-
shallowRef()对属性值修改之后,我们可以通过triggerRef()函数手动更新到视图;
-
shallowRef()在某些情况下执行属性值修改时,同步更新到视图层。ref 和 shallowRef 不能同时使用,会影响shallowRef造成视图更新,ref底层更新逻辑的时候,会调用triggerRef函数;
-
triggerRef 函数做强制更新;
-
小妙招:控制台设置,启用自定义格式化程序,试一试呦;
-
ref 获取dom元素
<div ref="dom">
<button @click="clickFn">改变</button>
</div>
const dom = ref<HTMLDivElement>()
const clickFn = () => {
console.log(dom.value?.innerHTML)
}
- shallowRef使用例子
<script lang="ts" setup>
import { ref, shallowRef } from 'vue'
type M = {
name: string
}
const message1 = ref<M>({
name: '小龙1'
})
const message2 = shallowRef<M>({
name: '小龙1'
})
const clickFn = () => {
// 不会更新视图
message2.value.name = '修改具体name值,不更新'
triggerRef(message2)
}
const clickFn = () => {
// 更新视图
message2.value = {
name: 'value 视图更新'
}
}
const clickFn = () => {
// 不会更新视图
message2.value.name = '修改具体name值,不更新'
// 调用 triggerRef 函数更新
triggerRef(message2)
}
const clickFn = () => {
// 原本不会更新视图,但是ref底层逻辑更新的时候,调用triggerRef函数,更新视图
message1.value.name = '带动更新'
message2.value.name = '修改具体name值,不更新'
}
</script>
- 自定义customRef
import { customRef } from 'vue'
// 自己实现的一个customRef,加简单的防抖
function myRef<T>(value: T) {
return customRef((track, trigger) => {
let timer: any
return {
get() {
// 收集依赖
track()
return value
},
set(newVal) {
// 出发依赖
clearTimeout(timer)
timer = setTimeout(() => {
timer = null
value = newVal
trigger()
}, 500)
}
}
})
}
// 使用 自定义的customRef
const obj = myRef<object>({
name: '小龙1'
})