[vue3]创建一个自定义的 ref

350 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

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

  • 实现防抖效果:

<template>
	<input type="text" v-model="keyword">
	<h3>{{keyword}}</h3>
</template>

<script>
	import {ref,customRef} from 'vue'
	export default {
		name:'Demo',
		setup(){
			// let keyword = ref('hello') //使用Vue准备好的内置ref
			//自定义一个myRef
			function myRef(value,delay){
				let timer
				//通过customRef去实现自定义
				return customRef((track,trigger)=>{
					return{
						get(){
							track() //告诉Vue这个value值是需要被“追踪”的
							return value
						},
						set(newValue){
							clearTimeout(timer)
							timer = setTimeout(()=>{
								value = newValue
								trigger() //告诉Vue去更新界面
							},delay)
						}
					}
				})
			}
			let keyword = myRef('hello',500) //使用程序员自定义的ref
			return {
				keyword
			}
		}
	}
</script>

(1)customRef 用于自定义返回一个ref对象,可以显式地控制依赖追踪和触发响应,接受工厂函数
(2)两个参数分别是用于追踪的 track 与用于触发响应的 trigger,并返回一个一个带有 get 和 set 属性的对象

使用:

	import {customRef} from 'vue';
	
	
    function useDebouncedRef(value) {
	      return customRef((track, trigger) => {
	        return {
	          get() {
	            track()	追踪当前数据
	            return value
	          },
	          set(newValue) {
	            value=newValue
	            trigger() 触发响应,即更新界面
	          },
	        }
	      })
	 }
	
	通过customRef返回的ref对象,和正常ref对象一样,通过x.value修改或读取值

类型声明:

	function customRef<T>(factory: CustomRefFactory<T>): Ref<T>

	type CustomRefFactory<T> = (
	  track: () => void,
	  trigger: () => void
	) => {
	  get: () => T
	  set: (value: T) => void
	}

使用场景

ref函数可以创建一个响应式数据,有时我们希望可以自己控制数据的触发响 应,就可以使用customRef函数自定义一个ref

写法

自定义ref的本质就是返回一个customRef函数,即rerturn customRef()

customRef接收两个参数

用于追踪的track,通知Vue去追踪value的变化
用于触发响应的trigger,通知Vue去重新解析模板
customRef函数需要返回带有get和set和对象\

为了防止每次修改都处触发一个新的定时器 我们在set函数外声明了一个变量来接收定时器返回的id 在下一次修改之后 我们先清除上一次还没有执行的定时器 在调用trigger() 通知Vue去重新解析模板