目录
一、ref
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value
property,指向该内部值。
1.简单示例:
<template>
<div>
1.simpleRef
value:{{simpleRef}}
<button @click="handleSimpleRef">点击+1</button>
</div>
</template>
<script setup lang='ts'>
import {simpleRef, handleSimpleRef} from './simpleRef';
</script>
<style>
</style>
//simpleRef.ts
// 引入ref
import {ref} from 'vue';
// 初始化ref
const simpleRef = ref(0);
// 使用.value获取以及更改ref的值
const handleSimpleRef = ()=>{
simpleRef.value++;
}
// 导出
export {
simpleRef,
handleSimpleRef
}
2.ref定义复杂结构。但是一般通过reactive处理复杂解构数据。
// 初始化ref
const simpleRef = ref({
obj:{
name:'hxshen'
}
});
// 使用.value获取以及更改ref的值
const handleSimpleRef = ()=>{
simpleRef.value.obj.name="new-name";
}
二、isRef
用于判断是否ref数据类型,返回boolean
const a = '1';
const b = ref(1);
isRef(a);//false
isRef(b);//true
三、unref
如果参数是一个 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val
的语法糖函数。
function useFoo(x: number | Ref<number>) {
const unwrapped = unref(x) // unwrapped 现在一定是数字类型
}
四、toRef
可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
// 创建一个非响应式对象
const plainObj = {
name:'plain-name',
value:'plain-val'
}
// 创建一个响应式对象
const reactObj = reactive({
name:'plain-name',
value:'plain-val'
});
const ref1 = toRef(plainObj,'name');
const ref2 = toRef(reactObj,'name');
const handle1 = ()=>{
//响应式不生效
ref1.value='ref1-name'
}
const handle2 = ()=>{
//响应式生效 且 reactObj 会相应改变
ref2.value='ref2-name'
}
五、toRefs
将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。解构出的对象也是响应式ref对象。
// 无法创建
const failRefObj = toRefs({
name:'plain-name',
value:'plain-val'
});
// 创建一个响应式对象
const reactObj = toRefs(reactive({
name:'plain-name',
value:'plain-val'
}));
// 解构一个响应式对象
const {name,value} = toRefs(reactive({
name:'plain-name',
value:'plain-val'
}));
//正常响应式处理
const handle1 = ()=>{
reactObj.name.value = 'name1'
reactObj.value.value = 'value1'
}
//正常响应式处理
const handle2 = ()=>{
name.value = 'name2'
value.value = 'value2'
}
六、customRef
创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track
和 trigger
函数作为参数,并且应该返回一个带有 get
和 set
的对象。
import { customRef } from 'vue'
function Myref<T>(value: T) {
return customRef((track, trigger) => {
return {
get() {
track()
// 自定义逻辑
console.log('get');
return value
},
set(newVal: T) {
// 自定义逻辑
console.log('set');
value = newVal
trigger()
}
}
})
}
let message = Myref<string|number>('error');
const changeMsg = () => {
message.value = 122222
}
此时方法调用后,会先执行一次set 再执行一次get
七、shallowRef
创建一个跟踪自身 .value
变化的 ref,其属性变化不是响应式的。
即,js中可以获取值,但是无法再模板中响应式变化
<template>
<div>
<p>message value:{{message}}</p>
<button @click="changeMsg">changeMsg</button>
</div>
<div>
<p>msgObj value:{{msgObj}}</p>
<button @click="changeMsgObj">changeMsgObj</button>
</div>
</template>
<script setup lang='ts'>
import { shallowRef } from 'vue'
const message = shallowRef<string>('first render')
const changeMsg = ()=>{
// 视图渲染
message.value = 'i am changed';
console.log("====message.value",message.value);
}
const msgObj = shallowRef({
title:'title',
content:'content'
})
const changeMsgObj = ()=>{
//视图会响应式渲染
//msgObj.value = {
// title:'title1',
// content:'content1'
//};
// 视图不会响应式渲染
msgObj.value.title = 'i am changed';
console.log("====msgObj.value",msgObj.value.title);
}
</script>
执行结果如下:
八、triggerRef
手动执行与 shallowRef 关联的任何作用 (effect)。
对第七例代码添加执行
const changeMsgObj = ()=>{
// 视图不会响应式渲染
msgObj.value.title = 'i am changed';
// 手动触发响应式
triggerRef(msgObj);
console.log("====msgObj.value",msgObj.value.title);
}
执行结果如下: