vue3 Refs系列

目录

一、ref

二、isRef

三、unref

四、toRef

五、toRefs

六、customRef

七、shallowRef

八、triggerRef


一、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);
}

执行结果如下:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值