一文了解customRef 自定义ref使用

概念

按照文档中的说明:customRef 可以用来创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 tracktrigger函数作为参数,并且应该返回一个带有 getset 的对象。
其实大致意思就是,我们可以按照自己的业务需求去自定义封装一个ref对象,在其内部可以使用getset去跟踪或更新数据,有点计算属性内味了哈~

应用场景

第一个应用场景就是官网文档中所提到的:可以用来实现防抖函数。

直接上代码:

<template>
  <input
    v-model="text"
  >
template>

<script setup lang="ts">
import { customRef } from 'vue'
function useDebouncedRef<T> (value: T, delay: number) {
  let timer: any = null
  return customRef<T>((track, trigger) => ({
    get () {
      track()
      return value
    },
    set (newValue) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        value = newValue
        // ...do something
        trigger()
      }, delay)
    }
  }))
}

const text = useDebouncedRef<string>('', 2000)
script>

代码很简单,相信大家一看就能懂~

第二个应用场景就是可以用来做一个加强型的计算属性。

在Vue3中,computed创建出来的计算属性是只读的。什么意思呢?就是 computed 创建出来的属性,只能通过自身的 get 函数去跟踪其他属性来进行自身更新,算是一个比较坑的地方吧:

img

所以这个时候可以用 customRef 来实现一个加强版的 computed,代码如下:

<template>
  <el-slider
    v-model="value"
    @change="handleSlider"
  />
template>

<script setup lang="ts">
import { customRef } from 'vue'

function useDebouncedRef<T> (value: T) {
  return customRef<T>((track, trigger) => ({
    get () {
      track()
      return value
    },
    set (newValue) {
      value = newValue
      trigger()
    }
  }))
}

const value = useDebouncedRef<number>(0)

function handleSlider (e: number) {
  value.value = e
}
script>

<style lang="scss" scoped>
style>


vue3的customRef实现自定义ref

  • customRef :创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制,我们可以手动写set和get里的逻辑
  • customRef就像一辆手动挡车可玩性高,ref就是自动挡车
  • 使用customRef实现防抖效果(在规定时间无论触发多少次方法,只执行最后一次),上代码
<template>
    
    <input type="text" v-model="word">
    <span>{{ word }}span>
template>
<script>
import { customRef } from 'vue';
export default {
    name: 'toRef',
    setup() {
        function myRef(value, delay) {
            return customRef((track, trigger) => { // 这里有两个参数
                let timer;// 用于接收定时器
                return {
                    get() {
                        console.log('get调用了');
                        // 读取数据时会自动调用该方法
                        track();// 这个方法会通知vue追踪value的变化
                        return value;
                    },
                    set(newValue) {// 有个参数,是新修改的数据我们在set里进行赋值
                        console.log('set调用了');
                        clearTimeout(timer);// 使用前先清空定时器,免得创建很多定时器,在输入时就会出现抖动的效果
                        // 修改数据时会自动调用该方法
                        timer = setTimeout(() => {
                            value = newValue;
                            trigger(); // 这个方法会通知vue去解析模版(解析就会调用get去获取新的数据了)
                        }, delay);
                    }
                }
            })
        };
        let word = myRef('a', 1000);
        return {
            word
        };
    }
}
script>

img

作用:创建一个自定义ref,比对其依赖项跟踪和更新触发进行显示控制

实现防抖效果:

// get:用于读数据进行调用    set:用于修改数据时进行调用
<template>
  <div>
    <input type="text" v-model="keyword" />
    <h3>{{ keyword }}h3>
  div>
template>
<script>
import { ref, reactive, toRaw, customRef } from "vue";
export default {
  setup() {
//自定义函数内部实现
    function myref(value) {
      let timer;
      return customRef((track, trigger) => {
        return {
          get() {
            //  读属性调用get
            console.log("从myref中读取数据我把${value}");
            track(); //通知vue追踪数据的变化
            return value;
          },
          set(newvalue) {
            //修改数据低啊用set
            console.log(`修改了数据${newvalue}`);
            value = newvalue; //进行修改数据
            clearTimeout(timer); //进行防抖
            timer = setTimeout(() => {
              trigger(); //通知vue重新解析模板
            }, 1000);
          },
        };
      });
    }
    let keyword = myref("hellow"); //使用程序员自定义ref
    return { keyword };
  },
};
script>

刚启动时:get调用两次进行读数据

img

当进行数据修改时:调用set函数,并且通过trigger()->track()进行数据的重新模板加载,实现响应式,

img

为了实现输入过快出现的抖动情况,

你可能感兴趣的:(Vue,vue.js,javascript,前端)