vue3知识点:customRef

  • Post author:
  • Post category:vue


在这里插入图片描述



三、其它 Composition API(不常用,了解即可)



4.customRef


  • 作用:

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


  • 实现防抖效果:

    所谓防抖效果指的是我输入框输入值停了,下方的显示才会实现更新修改,

    具体错误演示请看注意点7

<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:

问题:如图中,两个return分别指代什么?


答案:第1个return指代“把你自定义的ref函数交出去”,而第2个return指代“vue语法要求

,其中customeRef形参中的返回体必须返回一个对象,所以必须写return{}”

在这里插入图片描述


注意点2:

问题:绿色框中的get和set方法何时被调用?


答案:绿色框为自定义ref函数,红色框为调用方

,当红色框进行调用并传入hello参数给绿色框时,绿色框就相当于一个大盒子(或者叫“中转站容器”),

当模板<h3>和输入框<input>从绿色大盒子读取数据时,get就被调用了,当想修改绿色框大盒子中的属性值时,set就被调用了



在这里插入图片描述


注意点3:

问题:如下如图代码为啥打印了2次?


答案:

因为模板<h3>和输入框<input>各读取了一次keyWord属性

在这里插入图片描述

在这里插入图片描述


注意点4:

问题:想实现修改功能,为啥要写红框的代码?


答案:先说明下,myRef(value)中的形参value代表调用自定义函数传入的参数,而set(newValue)中的newValue代表输入框修改后的值,那get方法返回的value指代你传入的参数是啥,我就原封不动的返回出去。

问题:那为什么需要设置value = newValue才能实现<input>输入值后,<h3>标签就响应式更新值呢?


答案:

就在get方法的返回值那里,因为get返回了初始化传入的value属性值,而你后续如果想实现修改,那么必须把修改后的newValue值赋值给value才行,才能实现<input>修改值后,<h3>标签值也跟着响应式更新,否则无论<input>如何修改值,<h3>标签值压根不会改动。

在这里插入图片描述


注意点5:

问题:针对注意点4红框中,为啥要设置trigger(),trigger作用是啥?


答案:

设置value = newValue是把get要返回的value值给改了,但是你不通知它再重新触发一次解析模板操作,那么get()方法人家不会再调用一次啊

(大白话讲:value已经改了,但你得重新触发一次解析模板操作,这样修改后的值才能呈现在<h3>标签体中,否则页面值还是无法修改)

,图中代表调用set方法后应该执行的顺序

在这里插入图片描述


注意点6:

问题:针对注意点4中红框中设置track(),track作用是啥?


答案:

自定义ref函数中的get方法返回的value,它很矫情,不是你通过set方法修改了value值它就会返回最新值给页面,它生效的前提是必须设置track(),

这个track就相当于通知vue追踪数据的变化

,只要你返回 return value之前,调用track()进行通知追踪就会生效,就能实现<input>修改值后,<h3>标签值也跟着响应式更新,如果不写track()这句,页面还是不会响应式更新的。


注意点7:


需要把案例改成防抖模式,当前的还是存在bug问题如图:customRef-注意点7-未加防抖效果-错误结果展示.gif,感觉一直输入内容而展示效果动不动就退一下,

原因在于如图1,你定时器一直开着,就意味着相当于每次修改你都开一个定时器,而且当你输入频率比500毫秒块的时候就会把很多绿框的内容积压在一起,肯定会形成这个问题。

而添加防抖修改过后的正确展示如图:customRef-注意点7-加了防抖效果-正确结果展示.gif,


修改地方为:


  • 第1步:

    先let timer应以一个定时器

  • 第2步:

    然后每次开定时器都把返回值交出去

  • 第3步:

    最后每次进定时器之前,都把已存在的定时器清掉
let timer
clearTimeout(timer)
timer = setTimeout(()=>{
	value = newValue
	trigger() //通知Vue去重新解析模板
},500)

在这里插入图片描述



customRef-注意点7-未加防抖效果-错误结果展示.gif

在这里插入图片描述



customRef-注意点7-加了防抖效果-正确结果展示.gif

在这里插入图片描述



如图1



测试案例



完整代码

项目目录

在这里插入图片描述

main.js

//引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数
import { createApp } from 'vue'
import App from './App.vue'

//创建应用实例对象——app(类似于之前Vue2中的vm,但app比vm更“轻”)
const app = createApp(App)

//挂载
app.mount('#app')

App.vue

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

<script>
	import {ref,customRef} from 'vue'
	export default {
		name: 'App',
		setup() {
			//自定义一个ref——名为:myRef
			function myRef(value,delay){
				let timer
				return customRef((track,trigger)=>{
					return {
						get(){
							console.log(`有人从myRef这个容器中读取数据了,我把${value}给他了`)
							track() //通知Vue追踪value的变化(提前和get商量一下,让他认为这个value是有用的)
							return value
						},
						set(newValue){
							console.log(`有人把myRef这个容器中数据改为了:${newValue}`)
							clearTimeout(timer)
							timer = setTimeout(()=>{
								value = newValue
								trigger() //通知Vue去重新解析模板
							},delay)
						},
					}
				})
			}

			// let keyWord = ref('hello') //使用Vue提供的ref
			let keyWord = myRef('hello',500) //使用程序员自定义的ref
			
			return {keyWord}
		}
	}
</script>

结果展示:

在这里插入图片描述



本人其他相关文章链接

1.

《vue3第三章》其它 Composition API(不常用,了解即可),包括shallowReactive 与 shallowRef、readonly 与 shallowReadonly等等


2.

vue3知识点:shallowReactive 与 shallowRef


3.

vue3知识点:readonly 与 shallowReadonly


4.

vue3知识点:toRaw 与 markRaw


5.

vue3知识点:customRef


6.

vue3知识点:provide 与 inject


7.

vue3知识点:响应式数据的判断



版权声明:本文为a924382407原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。