官方阐述了怎么使用 customRef
自定义一个 ref
实现防抖,但是没有节流的代码,所以自己写了一个,区别不是很大。
概念
浅谈 JS 防抖和节流 可以看这篇文档了解什么是防抖和节流,讲的非常清晰,这里我就贴一下
CustomRef 用来自定义 ref
,它可以很好地跟踪依赖项和触发更新。它需要一个工厂函数,该函数接收 track
和 trigger
作为参数,这两个都是函数,就像 resolve
和 reject
,并且应该返回一个带有 get
和 set
的对象。
代码实现
防抖
<template>
<div class="container">
<label for="text">输入值: </label>
<input id="text" v-model="text" class="text" />
<div class="showText">{{ text }}</div>
</div>
</template>
<script setup>
import { ref, customRef } from 'vue'
// const text = ref('')
// const text = useDebouncedRef('', 500)
const text = useThrottleRef('', 50)
// customRef, 传入一个工厂函数,track ,trigger
// 返回一个对象, get, set
// 防抖
function useDebouncedRef(value, delay = 200) {
let t = null
return customRef((track ,tirgger) => {
return {
get() {
track()
return value
},
set(newVal) {
clearTimeout(t)
t = setTimeout(() => {
value = newVal
tirgger() // 告诉更新
}, delay)
}
}
})
}
</script>
<style>
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 400px;
}
.text {
width: 40%;
height: 20px;
}
.container .showText {
font-size: 32px;
margin: 20px;
color: rgb(240, 88, 28);
}
</style>
节流
// 节流
function useThrottleRef(value, delay = 200) {
let canRun = true
return customRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newVal) {
if(!canRun) return
canRun = false
setTimeout(() => {
value = newVal
canRun = true
trigger()
}, delay)
}
}
})
}