最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3中customRef自定義ref過程

 更新時間:2025年09月29日 08:53:17   作者:Rysxt  
Vue3的customRef允許自定義響應(yīng)式邏輯,通過get/set控制依賴追蹤與更新觸發(fā),適用于防抖、驗證、異步等場景,最佳實踐包括封裝函數(shù)、正確調(diào)用track/trigger、清理資源及優(yōu)化性能

一、customRef 基礎(chǔ)概念

??customRef?? 是 Vue3 提供的高級響應(yīng)式 API,用于創(chuàng)建??自定義行為的 ref 對象??。

與普通 ref(ref())的固定 getter/setter 邏輯不同,customRef 允許開發(fā)者??完全控制依賴追蹤和更新觸發(fā)??,適用于防抖、節(jié)流、異步更新、數(shù)據(jù)驗證等復(fù)雜場景。

其核心原理是通過??工廠函數(shù)??返回包含 getset 方法的對象:

  • get():讀取數(shù)據(jù)時觸發(fā),需調(diào)用 track() 告訴 Vue“這個值被依賴”;
  • set(newValue):修改數(shù)據(jù)時觸發(fā),需調(diào)用 trigger() 告訴 Vue“這個值更新了”。

二、customRef 基本用法

1. 創(chuàng)建簡單 customRef

以下代碼實現(xiàn)一個??基礎(chǔ) customRef??,功能與普通 ref 類型,但能更清晰地看到依賴追蹤和更新觸發(fā)的流程:

import { customRef } from 'vue';

// 工廠函數(shù):接收初始值,返回 customRef 對象
function useBasicRef(initialValue) {
  let value = initialValue; // 閉包保存值

  return customRef((track, trigger) => {
    return {
      // 讀取值時觸發(fā),調(diào)用 track() 收集依賴
      get() {
        track(); // 告訴 Vue 這個值被依賴(如模板中的 {{ value }})
        console.log('獲取值:', value);
        return value;
      },
      // 修改值時觸發(fā),調(diào)用 trigger() 通知更新
      set(newValue) {
        value = newValue; // 更新值
        console.log('設(shè)置值:', newValue);
        trigger(); // 通知 Vue 重新渲染依賴該值的組件
      }
    };
  });
}

// 在組件中使用
const basicRef = useBasicRef('初始值');

2. 與普通 ref 的區(qū)別

特性普通 ref (ref())customRef (customRef())
??邏輯控制??固定 getter/setter(僅實現(xiàn)基本響應(yīng)式)完全自定義(可插入驗證、防抖等邏輯)
??靈活性??高(滿足復(fù)雜場景需求)
??適用場景??基本響應(yīng)式需求(如存儲用戶輸入)需要特殊行為的場景(如延遲更新)

三、常見應(yīng)用場景與實現(xiàn)

1. 防抖 ref(延遲更新)

??場景??:用戶輸入時,避免頻繁觸發(fā)視圖更新(如搜索框輸入),僅在停止輸入后更新。

import { customRef } from 'vue';

function useDebouncedRef(initialValue, delay = 500) {
  let timer = null; // 閉包保存定時器
  let value = initialValue;

  return customRef((track, trigger) => {
    return {
      get() {
        track(); // 收集依賴
        return value;
      },
      set(newValue) {
        clearTimeout(timer); // 清除之前的定時器
        timer = setTimeout(() => {
          value = newValue; // 延遲后更新值
          trigger(); // 觸發(fā)更新
        }, delay);
      }
    };
  });
}

// 在組件中使用
const searchQuery = useDebouncedRef('', 500);
// 模板中:<input v-model="searchQuery" />

??效果??:用戶輸入時,視圖不會立即更新,僅在停止輸入 500ms 后更新。

2. 數(shù)據(jù)驗證 ref

??場景??:輸入數(shù)據(jù)時,實時驗證合法性(如郵箱格式、年齡范圍),若不合法則提示錯誤。

import { customRef } from 'vue';

function useValidatedRef(initialValue, validator) {
  let value = initialValue;
  let error = null;

  return customRef((track, trigger) => {
    return {
      get() {
        track(); // 收集依賴
        return { value, error }; // 返回值和錯誤信息
      },
      set(newValue) {
        const validationResult = validator(newValue); // 驗證數(shù)據(jù)
        if (validationResult === true) {
          value = newValue; // 驗證通過,更新值
          error = null;
        } else {
          error = validationResult; // 驗證失敗,保存錯誤信息
        }
        trigger(); // 觸發(fā)更新(視圖會顯示錯誤信息)
      }
    };
  });
}

// 驗證函數(shù):檢查年齡是否在 18-120 之間
const ageValidator = (value) => {
  if (typeof value !== 'number' || value < 18 || value > 120) {
    return '年齡必須在 18-120 之間';
  }
  return true;
};

// 在組件中使用
const age = useValidatedRef(20, ageValidator);
// 模板中:<input v-model.number="age.value" /><span v-if="age.error" style="color: red">{{ age.error }}</span>

??效果??:輸入非法年齡(如 10)時,會顯示錯誤提示。

3. 異步 ref(異步更新)

??場景??:從服務(wù)器獲取數(shù)據(jù)后,更新 ref 的值(如用戶信息加載)。

import { customRef } from 'vue';

function useAsyncRef(asyncFunction) {
  let value = null;
  let isLoading = true;

  return customRef((track, trigger) => {
    return {
      get() {
        track(); // 收集依賴
        return { value, isLoading }; // 返回值和加載狀態(tài)
      },
      set(newValue) {
        // 觸發(fā)異步操作(如獲取用戶信息)
        asyncFunction(newValue).then((data) => {
          value = data; // 更新值
          isLoading = false; // 結(jié)束加載
          trigger(); // 觸發(fā)更新
        }).catch((error) => {
          console.error('異步操作失敗:', error);
          isLoading = false; // 結(jié)束加載
          trigger(); // 觸發(fā)更新
        });
      }
    };
  });
}

// 模擬異步函數(shù):獲取用戶信息
const fetchUserInfo = (userId) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ id: userId, name: '張三' });
    }, 1000);
  });
};

// 在組件中使用
const userInfo = useAsyncRef(fetchUserInfo);
// 模板中:<div v-if="userInfo.isLoading">加載中...</div><div v-else>{{ userInfo.value.name }}</div>

??效果??:設(shè)置 userInfo.value 為 userId 后,會顯示“加載中...”,1 秒后顯示用戶姓名。

四、best 實踐

1. 封裝為組合式函數(shù)

將 customRef 邏輯封裝為獨(dú)立的組合式函數(shù)(如 useDebouncedRefuseValidatedRef),提高代碼復(fù)用性。避免在組件中重復(fù)編寫 get/set 邏輯。

2. 正確處理依賴

get 方法中??必須調(diào)用 track()??,否則 Vue 無法追蹤依賴,導(dǎo)致視圖不更新;在 set 方法中??必須調(diào)用 trigger()??,否則視圖不會重新渲染。

3. 避免內(nèi)存泄漏

若 customRef 中使用了定時器、事件監(jiān)聽器等資源,需在組件卸載時清理(如 onUnmounted 鉤子中清除定時器),防止內(nèi)存泄漏。

4. 性能優(yōu)化

  • 避免在 get 方法中執(zhí)行昂貴計算(如復(fù)雜循環(huán)),可將結(jié)果緩存;
  • set 方法中,可通過比較新舊值(如 if (newValue !== value))避免不必要的更新。

通過以上教程,你可以掌握 Vue3 中 customRef 的基本用法和常見場景,靈活實現(xiàn)自定義響應(yīng)式邏輯。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue3路由query參數(shù)實例詳解

    Vue3路由query參數(shù)實例詳解

    文章介紹了Vue3路由的query參數(shù),包括其定義、使用方法以及如何在組件中接收和展示query參數(shù),通過一個簡單的實例,展示了如何在路由配置中添加query參數(shù),并在子組件中通過計算屬性獲取和顯示這些參數(shù),感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • vue項目打包后上傳至GitHub并實現(xiàn)github-pages的預(yù)覽

    vue項目打包后上傳至GitHub并實現(xiàn)github-pages的預(yù)覽

    這篇文章主要介紹了vue項目打包后上傳至GitHub并實現(xiàn)github-pages的預(yù)覽,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • vue中對接Graphql接口的實現(xiàn)示例

    vue中對接Graphql接口的實現(xiàn)示例

    本文主要介紹了vue中對接Graphql接口的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • Vue.js中computed的基本使用方法

    Vue.js中computed的基本使用方法

    Vue.js中,computed屬性根據(jù)依賴進(jìn)行緩存,只有依賴改變時才重新計算,這樣有效提高性能,computed屬性是響應(yīng)式的,可以自動更新,并且默認(rèn)是只讀的,它與methods的主要區(qū)別在于計算屬性具有緩存性,而方法每次調(diào)用都會執(zhí)行,使用computed可以使模板更加簡潔,提高應(yīng)用性能
    2024-09-09
  • vue項目引入svg圖標(biāo)的完整步驟

    vue項目引入svg圖標(biāo)的完整步驟

    在實際的項目開發(fā)中,使用svg圖標(biāo)占用內(nèi)存比圖片更小,映入圖片內(nèi)存比較大,同時也適用于不同屏幕的尺寸,下面這篇文章主要給大家介紹了關(guān)于vue項目引入svg圖標(biāo)的完整步驟,需要的朋友可以參考下
    2022-10-10
  • vue路由守衛(wèi),限制前端頁面訪問權(quán)限的例子

    vue路由守衛(wèi),限制前端頁面訪問權(quán)限的例子

    今天小編就為大家分享一篇vue路由守衛(wèi),限制前端頁面訪問權(quán)限的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • 使用vue-cli導(dǎo)入Element UI組件的方法

    使用vue-cli導(dǎo)入Element UI組件的方法

    這篇文章給大家介紹了使用vue-cli導(dǎo)入Element UI組件的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友一起看看吧
    2018-05-05
  • 一文帶你快速了解Vue3服務(wù)端渲染SSR

    一文帶你快速了解Vue3服務(wù)端渲染SSR

    在當(dāng)今前端開發(fā)領(lǐng)域,首屏加載速度和 SEO 優(yōu)化已成為衡量 Web 應(yīng)用質(zhì)量的重要指標(biāo),Vue3服務(wù)端渲染為解決這些問題提供了優(yōu)雅的解決方案,下面小編就來和大家詳細(xì)講講吧
    2025-05-05
  • Vue雙向綁定原理深度剖析

    Vue雙向綁定原理深度剖析

    Vue雙向綁定是MVVM框架的核心特性,通過數(shù)據(jù)劫持Object.defineProperty或Proxy、依賴收集和模板編譯三大模塊實現(xiàn),這篇文章主要介紹了Vue雙向綁定原理的相關(guān)資料,需要的朋友可以參考下
    2026-03-03
  • vue如何集成raphael.js中國地圖的方法示例

    vue如何集成raphael.js中國地圖的方法示例

    最近的數(shù)據(jù)統(tǒng)計項目中要用到中國地圖,也就是在地圖上動態(tài)的顯示某個時間段某個省份地區(qū)的統(tǒng)計數(shù)據(jù),我們不需要flash,僅僅依靠raphael.js以及SVG圖像就可以完成地圖的交互操作。本文就給大家介紹了關(guān)于利用vue集成raphael.js中國地圖的相關(guān)資料,需要的朋友可以參考下。
    2017-08-08

最新評論

玉门市| 隆回县| 吴江市| 昌乐县| 略阳县| 嘉义县| 巴里| 巴彦淖尔市| 定日县| 石景山区| 静安区| 珠海市| 沁水县| 隆昌县| 长泰县| 都匀市| 正定县| 义乌市| 措美县| 杭锦旗| 花垣县| 五原县| 望江县| 乡城县| 郸城县| 堆龙德庆县| 邮箱| 康马县| 五河县| 汤原县| 区。| 重庆市| 观塘区| 武陟县| 库尔勒市| 康乐县| 德格县| 乌兰县| 克东县| 麻栗坡县| 伊通|