一.Vue3中普通Ref的属性

        在Vue3中,ref()接受一个内部值,它返回的是一个ref对象,这个对象是响应式的,可以更改的,且只有一个指向其内部属性值的属性value。ref()将传入参数的值包装为一个带value属性的ref对象。

      1.1.Ref是可更改的:

             ref是可更改的,如果定义一个ref,返回的ref对象是可以通过.value的方式为该ref赋予一个新的值。

代码示例如下:

let a=ref(1)
a.value=10
console.log('a的值',a);

    根据上面的演示可以看出,更改ref对象的.value属性就可以为ref对象赋予一个新的值,需要注意的是,更改后的ref对象的值,内存地址也发生变化了,属于深层次的更改。

1.2.Ref对象是响应式的

         Ref对象是响应式的,也就是说所有的对ref的.value操作都会被追踪,并且写操作会触发与之相关的副作用。更改了ref对象的.value,在页面渲染的时候会追踪到ref对象中.value的变化,页面也会发生相应的改变,示例如下:

<header>这是父组件的内容</header>
<h2>{{ name }}</h2>
let name=ref("张峻豪")

根据上述代码,页面显示如下:

当我对ref对象的.value属性进行更改时:

<header>这是父组件的内容</header>
<h2>{{ name }}</h2>
let name=ref("张峻豪")
name.value="张极"

页面在渲染的时候就会追踪到ref对象.value的变化,页面内容会发生改变:

以上的示例就是ref响应式的简单应用。

 二.普通ref的不足:

        虽然vue3中ref属性既可以更改又可以实现响应式,但是在实际使用vue3开发的过程中,直接使用ref可能会带来一些弊端或者是性能上的不足,举一个实际应用场景中的例子,假如要实现一个表单功能,用户在输入框输入一些用户的信息,会向服务器的借口返回用户输入的用户信息,试想一下,如果使用普通的ref来获取用户输入的信息,就会导致用户在输入信息的时候,会不断的向后端接口返回用户输入的信息,这样的话,不仅不对后端接口的资源产生浪费,而且在逻辑上也不是很合理。我们需要对这个功能进行的改进时,当用户输入的内容在一定时间内不发生更改时,再向后端接口返回用户输入的信息,这样不仅不会造成资源的浪费,而且在逻辑上也比较合理,这个时候,我们就可以使用customRef(自定义ref)

三.CustomRef的使用:

       3.1CustomRef与 普通Ref的区别:

            CustomRef直白简单的理解就是在使用普通Ref对象的时候添加一些自己的逻辑 ,自定义的Ref,本质上是一个函数,所有在实际的使用场景中一般把customRef的逻辑封装在一个hooks文件中,然后对外暴露出去,就可以在所有的组件之中使用自己定义的ref的逻辑。

         3.2CustomRef的使用:

            自定义ref的回调中接收两个参数,一个是track,另一个是trigger,它们都是函数。这两个函数分别在getter函数和setter函数中调用。在ref内部,get函数是在一个数据被读取的时候调用的,而set函数是在数据被修改的时候调用的。在get函数内部接收track函数,是通知Vue对目标数据进行持续关注;set函数中接收trigger函数,就会通知Vue关注的数据变化了,重新解析该模板,页面渲染发生相应的变化。

        3.3CustomRef的实际运用:

             自定义ref的回调中接收两个参数,一个是track,另一个是trigger,它们都是函数。这两个函数分别在getter函数和setter函数中调用。在ref内部,get函数是在一个数据被读取的时候调用的,而set函数是在数据被修改的时候调用的。在get函数内部接收track函数,是通知Vue对目标数据进行持续关注;set函数中接收trigger函数,就会通知Vue关注的数据变化了,重新解析该模板,页面渲染发生相应的变化。

               如果现在有这样一个需求,在输入框中输入用户信息,上面的h3标签里的内容延迟500ms更新

               首先我们要在hooks文件中写入我们自己自定义ref的逻辑,先创建一个useMsgRef.js写入我们自定义的Ref的逻辑。

                useMsgRef.js

import { customRef } from "vue";
export default function(initValue,delay){
    let timer;
    let msg=customRef((track,trigger)=>{
          return{
            //get在数据读取的时候被调用
            get(){
             track()//告诉vue对该数据持续关注
             return initValue;
            },
            //set在数据修改的时候被调用
            set(value){
            clearTimeout(timer)
            timer= setTimeout(() => {
                initValue=value;
                trigger()//通知vue关注的数据变化了
             }, delay);
            }
          }
    })
    //对外暴露出去自己定义的Ref的逻辑
    return {msg};
}

       Father.vue

<h2>{{ msg }}</h2>
<input type="text" v-model="msg">
import useMsgRef from '@/hooks/useMsgRef';
//给自定义ref传递一个初始值和延时时长
let {msg}=useMsgRef('张峻豪',500)

当我改变用户信息时,页面h3里面的内容并不会马上发生改变:

在经过500ms后,页面渲染的内容就会发生改变

以上就是使用自定义ref的一个简单例子。在实际开发的过程中,自定义ref的使用一般和js中的防抖节流结合使用,使项目的逻辑功能更加完善,性能更好。

Logo

前往低代码交流专区

更多推荐