Ref全家桶
由于ref返回的是一个ES6的class类,要修改ref的值要通过.value来进行修改。
isRef
用于判断是不是ref,用法为
vue
12345
<script setup>
import { isRef, ref } from 'vue';
const Cain = ref({name: "Cain"})
isRef(Cain)//返回一个布尔值
</script>
shallowRef
ref实现深层次的响应,shallowRef实现浅层的响应
vue
1234567891011121314151617
<template>
<button @click="change" style="width: 200px;height: 200px;">修改</button>
<div>
<h1>ref:{{ Cain }}</h1>
<h1>shallowRef:{{ Cain2 }}</h1>
</div>
</template>
<script setup>
import { ref, shallowRef } from "vue";
const Cain = ref({ name: "Cain" });
const Cain2 = shallowRef({ name: "Cain2" });
const change = () => {
Cain2.value.name = "Cain3";
console.log(Cain2);
};
</script>
点击按钮前,视图效果如下:
点击按钮后,视图效果没有变化,控制台输出:
说明值变化了,但是视窗没有变化,这是因为shallowRef的响应是浅层的,shallowRef的响应只到.value处,如果要实现修改shallowRef的效果需要直接修改.value
vue
123456789
<script setup>
import { ref, shallowRef } from "vue";
const Cain = ref({ name: "Cain" });
const Cain2 = shallowRef({ name: "Cain2" });
const change = () => {
Cain2.value = { name: "Cain3" };//修改成这样就可以实现响应了
console.log(Cain2);
};
</script>
视窗显示:
可以看到视图成功响应了,但是有一个地方需要注意就是如果ref跟shallowRef写到一起就会引起shallowRef跟ref一起变化
vue
12345678910111213
<script setup>
import { ref, shallowRef } from "vue";
const Cain = ref({ name: "Cain" });
const Cain2 = shallowRef({ name: "Cain2" });
//如果这样写的话shallowRef就会被ref影响到改变
const change = () => {
Cain.value.name = "我是ref"
Cain2.value.name = "我被影响了";
console.log(Cain2);
};
</script>
这是因为ref更新底层会调用triggerRef
vue
123456789101112
<script setup>
import { ref, shallowRef, triggerRef } from "vue";
const Cain = ref({ name: "Cain" });
const Cain2 = shallowRef({ name: "Cain2" });
//如果这样写的话shallowRef也会更新
const change = () => {
Cain2.value.name = "我被影响了";
triggerRef(Cain2)
console.log(Cain2);
};
</script>
效果如下:
customRef
用于自己实现ref功能,但是可以在ref更新过程中加入一些自己的逻辑,例如防抖,下面是自己实现一个最简易的ref代码
vue
123456789101112131415161718192021222324
<script setup lang="ts">
import { customRef, ref, shallowRef, triggerRef } from "vue";
const Cain = ref({ name: "Cain" });
const Cain2 = shallowRef({ name: "Cain2" });
//实现一个最基础的ref
function MyRef<T>(value: T) {
return customRef((track, trigger) => {
return {
get(){
track()//收集依赖
return value
},
set(newVal){
value = newVal
trigger()//更新依赖
}
}
})
}
const myRef = MyRef<string>("myCain")
const change = () => {
myRef.value = "我被修改了"
}
</script>
以下是最简单的防抖功能实现
vue
123456789101112131415161718192021222324252627282930
<script setup lang="ts">
import { customRef, ref, shallowRef, triggerRef } from "vue";
const Cain = ref({ name: "Cain" });
const Cain2 = shallowRef({ name: "Cain2" });
//实现一个最基础的防抖
function MyRef<T>(value: T) {
let timer: any;
return customRef((track, trigger) => {
return {
get() {
track(); //收集依赖
return value;
},
set(newVal) {
clearTimeout(timer);
timer = setTimeout(() => {
console.log("调用了接口")
timer = null
value = newVal;
trigger(); //更新依赖
},500);
},
};
});
}
const myRef = MyRef<string>("myCain");
const change = () => {
myRef.value = "我被修改了";
};
</script>




