Vue3利用自定義ref實(shí)現(xiàn)防抖功能
<script setup>
import { debounceRef } from './ref';
const text = debounceRef('',1000)
</script>
<template>
<div>
<input v-model="text">
</div>
<div>{{text}}</div>
</template>
<style scoped>
</style>我們想實(shí)現(xiàn)這樣的效果:輸入框中雙向綁定了一個響應(yīng)式數(shù)據(jù)text,當(dāng)我們從輸入框中改變text中的值時,我們想要text的值過一定的時間再做變更,類似一個防抖效果。
所以上面的關(guān)鍵就是實(shí)現(xiàn)debounceRef()這個函數(shù)
debounceRef(value,delay)
import { customRef } from "vue";
export function debounceRef(value,delay = 1000){
let timer;
return customRef((track,trigger) =>({
get(){
//依賴收集
track()
return value
},
set(val){
clearTimeout(timer)
timer = setTimeout(()=>{
//派發(fā)更新
trigger()
value = val
},delay)
}
}))
}函數(shù)接收兩個參數(shù):
第一個參數(shù),綁定的值。
第二個參數(shù),想要延遲多少秒更新
我們利用了vue內(nèi)部提供的一個實(shí)現(xiàn)自定義ref的函數(shù),該函數(shù)接收一個工廠函數(shù),該函數(shù)必須返回一個對象,其中包含get和set函數(shù)
customRef()源碼
export function customRef<T>(factory: CustomRefFactory<T>): Ref<T> {
return new CustomRefImpl(factory) as any
}
export type CustomRefFactory<T> = (
track: () => void,
trigger: () => void,
) => {
get: () => T
set: (value: T) => void
}CustomRefImpl源碼
class CustomRefImpl<T> {
public dep?: Dep = undefined
private readonly _get: ReturnType<CustomRefFactory<T>>['get']
private readonly _set: ReturnType<CustomRefFactory<T>>['set']
public readonly __v_isRef = true
constructor(factory: CustomRefFactory<T>) {
const { get, set } = factory(
() => trackRefValue(this),
() => triggerRefValue(this),
)
this._get = get
this._set = set
}
get value() {
return this._get()
}
set value(newVal) {
this._set(newVal)
}
}CustomRefImpl類中主要做了兩件事,依賴收集trackRefValue和派發(fā)更新triggerRefValue。
trackRefValue()
export function trackRefValue(ref: RefBase<any>) {
if (shouldTrack && activeEffect) {
ref = toRaw(ref)
trackEffect(
activeEffect,
(ref.dep ??= createDep(
() => (ref.dep = undefined),
ref instanceof ComputedRefImpl ? ref : undefined,
)),
__DEV__
? {
target: ref,
type: TrackOpTypes.GET,
key: 'value',
}
: void 0,
)
}
}triggerRefValue()
export function triggerRefValue(
ref: RefBase<any>,
dirtyLevel: DirtyLevels = DirtyLevels.Dirty,
newVal?: any,
) {
ref = toRaw(ref)
const dep = ref.dep
if (dep) {
triggerEffects(
dep,
dirtyLevel,
__DEV__
? {
target: ref,
type: TriggerOpTypes.SET,
key: 'value',
newValue: newVal,
}
: void 0,
)
}
}總結(jié)
ref的原理也是這樣,依賴收集trackRefValue和派發(fā)更新triggerRefValue
到此這篇關(guān)于Vue3利用自定義ref實(shí)現(xiàn)防抖功能的文章就介紹到這了,更多相關(guān)Vue3 ref防抖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue?使用mescroll.js框架實(shí)現(xiàn)下拉加載和上拉刷新功能
這篇文章主要介紹了vue?使用mescroll.js框架?實(shí)現(xiàn)下拉加載和上拉刷新功能,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
Vue+Flask實(shí)現(xiàn)簡單的登錄驗證跳轉(zhuǎn)的示例代碼
本篇文章主要介紹了Vue+Flask實(shí)現(xiàn)簡單的登錄驗證跳轉(zhuǎn)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
vue如何實(shí)現(xiàn)動態(tài)的選中狀態(tài)切換效果
這篇文章主要介紹了vue如何實(shí)現(xiàn)動態(tài)的選中狀態(tài)切換效果,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04
Vue實(shí)現(xiàn)實(shí)時刷新時間的功能
這篇文章主要為大家詳細(xì)介紹了如何Vue利用實(shí)現(xiàn)實(shí)時刷新時間的功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,感興趣的小伙伴可以了解下2023-12-12
Vue.js實(shí)現(xiàn)文件上傳和進(jìn)度條顯示功能
在現(xiàn)代Web開發(fā)中,文件上傳是一個常見而重要的需求,無論是在用戶上傳頭像、文檔或者其他類型的文件時,良好的用戶體驗都是至關(guān)重要的,在這篇博客中,我們將介紹如何使用Vue.js來實(shí)現(xiàn)文件上傳功能,同時顯示上傳進(jìn)度條,需要的朋友可以參考下2024-11-11

