Vue3中自定义Ref的使用

一.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中的防抖节流结合使用,使项目的逻辑功能更加完善,性能更好。

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3自定义hook其实就是一个普通的函数,该函数可以使用Vue3的响应式API和生命周期钩子。自定义hook的目的是将一些逻辑抽象出来,使组件逻辑更加清晰。 自定义hook的命名一般以"use"开头,例如"useFetch","useLocalStorage"等。下面是一个示例: ```js import { ref, onMounted } from 'vue' export function useFetch(url) { const data = ref(null) const isLoading = ref(false) const error = ref(null) onMounted(async () => { isLoading.value = true try { const response = await fetch(url) data.value = await response.json() } catch (err) { error.value = err.message } finally { isLoading.value = false } }) return { data, isLoading, error } } ``` 在上面的代码,我们定义了一个名为"useFetch"的自定义hook,它接受一个URL作为参数,并返回一个包含数据、加载状态和错误的响应式对象。在这个hook,我们使用Vue3的ref函数来创建响应式数据,使用onMounted钩子来在组件挂载时执行异步请求。最后,我们将数据、加载状态和错误返回给调用该hook的组件。 可以在组件使用这个自定义hook,如下所示: ```js <template> <div v-if="isLoading">Loading...</div> <div v-else-if="error">{{ error }}</div> <div v-else>{{ data }}</div> </template> <script> import { useFetch } from './useFetch' export default { setup() { const { data, isLoading, error } = useFetch('https://jsonplaceholder.typicode.com/todos/1') return { data, isLoading, error } } } </script> ``` 在上面的代码,我们从我们的自定义hook导入了"data"、"isLoading"和"error",然后将它们返回给组件。组件可以直接使用这些响应式数据,而不必担心如何处理异步请求的细节。这使得组件的代码更加简洁和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值