欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3使用Proxy構(gòu)建高效響應(yīng)式數(shù)據(jù)的示例代碼

 更新時(shí)間:2025年03月04日 08:51:23   作者:奇舞精選  
在 Vue 3 中,Proxy 主要用于 攔截對(duì)象的基本操作,包括 屬性讀?。╣et)、修改(set)、刪除(deleteProperty) 等,本文給大家介紹了Vue3使用Proxy構(gòu)建高效響應(yīng)式數(shù)據(jù)的操作教程,需要的朋友可以參考下

Proxy 的核心機(jī)制

在 Vue 3 中,Proxy 主要用于 攔截對(duì)象的基本操作,包括 屬性讀?。╣et)、修改(set)、刪除(deleteProperty) 等。這是 Vue 3 取代 Object.defineProperty 的根本原因。

Proxy 允許攔截的操作:

操作作用
get(target, key, receiver)讀取屬性時(shí)觸發(fā)
set(target, key, value, receiver)設(shè)置屬性時(shí)觸發(fā)
deleteProperty(target, key)刪除屬性時(shí)觸發(fā)
has(target, key)判斷 key 是否存在(key in obj)
ownKeys(target)獲取對(duì)象的所有鍵(Object.keys(obj))
apply(target, thisArg, args)代理函數(shù)調(diào)用
construct(target, args)代理 new 操作符

Proxy 的核心實(shí)現(xiàn)

讓我們通過一個(gè) 手寫 Proxy 劫持 的例子,模擬 Vue 3 響應(yīng)式數(shù)據(jù)的基本實(shí)現(xiàn):

const handler = {
  get(target, key) {
    console.log(`讀取屬性:${key}`);
    return Reflect.get(target, key);
  },
  set(target, key, value) {
    console.log(`修改屬性:${key} -> ${value}`);
    return Reflect.set(target, key, value);
  }
};

const data = { message: "Hello Vue 3" };
const proxyData = new Proxy(data, handler);

console.log(proxyData.message); // 讀取屬性:message
proxyData.message = "Updated"; // 修改屬性:message -> Updated

解讀:

? • Reflect.get(target, key):用于獲取目標(biāo)對(duì)象的值,等價(jià)于 target[key]。

? • Reflect.set(target, key, value):用于修改目標(biāo)對(duì)象的值,等價(jià)于 target[key] = value。

? • Vue 3 就是基于 Proxy 設(shè)計(jì) reactive() 來創(chuàng)建響應(yīng)式數(shù)據(jù)。

Vue 3 如何基于 Proxy 構(gòu)建響應(yīng)式系統(tǒng)

Vue 3 的核心響應(yīng)式 API reactive() 就是對(duì) Proxy 的封裝,具體實(shí)現(xiàn)如下:

function reactive(target) {
  if (typeof target !== "object" || target === null) {
    return target;
  }

  return new Proxy(target, {
    get(target, key, receiver) {
      console.log(`訪問屬性:${key}`);
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      console.log(`修改屬性:${key} -> ${value}`);
      return Reflect.set(target, key, value, receiver);
    }
  });
}

const state = reactive({ count: 0 });

console.log(state.count); // 訪問屬性:count
state.count++; // 修改屬性:count -> 1

Vue 3 reactive() 實(shí)現(xiàn)的核心點(diǎn)

? 1. 使用 Proxy 劫持整個(gè)對(duì)象,而不是每個(gè)屬性。

? 2. 支持深層次代理(但 Vue 3 默認(rèn)是惰性代理,訪問時(shí)才創(chuàng)建嵌套對(duì)象的代理)。

? 3. 攔截?cái)?shù)組和對(duì)象的方法(如 push、pop、delete) 。

Vue 3 的依賴收集與副作用處理機(jī)制

Vue 3 采用 “響應(yīng)式依賴收集 + 依賴觸發(fā)” 來完成視圖更新,核心組件包括:

? • reactive():創(chuàng)建響應(yīng)式數(shù)據(jù)(基于 Proxy)。

? • effect():收集依賴,記錄哪些屬性被訪問。

? • trigger():數(shù)據(jù)變更時(shí)通知所有依賴執(zhí)行。

1. Vue 3 依賴收集的核心實(shí)現(xiàn)

let activeEffect = null; // 當(dāng)前正在執(zhí)行的 effect
const targetMap = new WeakMap(); // 存儲(chǔ)依賴

function effect(fn) {
  activeEffect = fn;
  fn(); // 立即執(zhí)行一次,收集依賴
  activeEffect = null;
}

function track(target, key) {
  if (activeEffect) {
    let depsMap = targetMap.get(target);
    if (!depsMap) {
      depsMap = new Map();
      targetMap.set(target, depsMap);
    }
    let deps = depsMap.get(key);
    if (!deps) {
      deps = new Set();
      depsMap.set(key, deps);
    }
    deps.add(activeEffect);
  }
}

function trigger(target, key) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return;
  const effects = depsMap.get(key);
  if (effects) {
    effects.forEach(fn => fn()); // 觸發(fā)所有依賴
  }
}

// 結(jié)合 Proxy 創(chuàng)建 Vue 3 響應(yīng)式對(duì)象
function reactive(target) {
  return new Proxy(target, {
    get(target, key, receiver) {
      track(target, key); // 依賴收集
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      const result = Reflect.set(target, key, value, receiver);
      trigger(target, key); // 觸發(fā)更新
      return result;
    }
  });
}

2. Vue 3 響應(yīng)式數(shù)據(jù)的完整示例

const state = reactive({ count: 0 });

effect(() => {
  console.log(`count 更新:${state.count}`);
});

state.count++; // 觸發(fā)更新:count 更新:1
state.count = 5; // 觸發(fā)更新:count 更新:5

執(zhí)行流程:

? 1. effect(() => console.log(state.count)) 執(zhí)行時(shí),觸發(fā) get(),收集 state.count 的依賴。

? 2. state.count++ 觸發(fā) set(),調(diào)用 trigger() 通知所有依賴執(zhí)行 effect()。

Vue 3 Proxy 響應(yīng)式系統(tǒng)的優(yōu)化

1. 依賴按需收集

Vue 2 在初始化時(shí)遍歷整個(gè)對(duì)象,而 Vue 3 只有在 訪問屬性時(shí)才進(jìn)行代理,減少性能消耗。

2. 自動(dòng)清理無效依賴

Vue 3 采用 WeakMap + Set 進(jìn)行依賴存儲(chǔ),避免內(nèi)存泄漏,Vue 2 需要手動(dòng)管理依賴刪除。

3. 只更新受影響的組件

Vue 3 的 trigger() 機(jī)制讓每個(gè)組件只更新它所依賴的部分,避免 Vue 2 中全局重新計(jì)算的問題。

總結(jié)

Proxy 使 Vue 3 的響應(yīng)式系統(tǒng)更高效,支持新增屬性監(jiān)聽、數(shù)組操作攔截等。依賴追蹤采用 WeakMap + Set 存儲(chǔ),提高性能,避免 Vue 2 的內(nèi)存泄漏問題。 Vue 3 采用 Lazy Proxy(惰性代理),只有訪問屬性時(shí)才進(jìn)行代理,減少初始化開銷。Vue 3 的響應(yīng)式機(jī)制通過effect() 進(jìn)行自動(dòng)依賴收集,讓數(shù)據(jù)更新更智能、更高效。

以上就是Vue3使用Proxy構(gòu)建高效響應(yīng)式數(shù)據(jù)的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Vue3 Proxy響應(yīng)式數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 在vue中使用echarts圖表實(shí)例代碼詳解

    在vue中使用echarts圖表實(shí)例代碼詳解

    本文通過實(shí)例代碼給大家介紹了在vue中使用echarts圖表的方法,需要注意的事項(xiàng)文中給大家提到,需要的朋友可以參考下
    2018-10-10
  • Vue文件下載進(jìn)度條的實(shí)現(xiàn)過程

    Vue文件下載進(jìn)度條的實(shí)現(xiàn)過程

    這篇文章主要介紹了Vue文件下載進(jìn)度條的實(shí)現(xiàn)原理,通過使用onDownloadProgress方法API獲取進(jìn)度及文件大小等數(shù)據(jù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Vue2+SpringBoot實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出到csv文件并下載的使用示例

    Vue2+SpringBoot實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出到csv文件并下載的使用示例

    本文主要介紹了Vue2+SpringBoot實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出到csv文件并下載,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-10-10
  • vue+webpack模擬后臺(tái)數(shù)據(jù)的示例代碼

    vue+webpack模擬后臺(tái)數(shù)據(jù)的示例代碼

    這篇文章主要介紹了vue+webpack模擬后臺(tái)數(shù)據(jù)的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • 基于vue實(shí)現(xiàn)一個(gè)神奇的動(dòng)態(tài)按鈕效果

    基于vue實(shí)現(xiàn)一個(gè)神奇的動(dòng)態(tài)按鈕效果

    今天我們將利用vue的條件指令來完成一個(gè)簡(jiǎn)易的動(dòng)態(tài)變色功能按鈕,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2019-05-05
  • 導(dǎo)致VUE頁面不刷新的問題分析及解決方法

    導(dǎo)致VUE頁面不刷新的問題分析及解決方法

    由于 Vue 會(huì)在初始化實(shí)例時(shí)對(duì) property 執(zhí)行 getter/setter 轉(zhuǎn)化,所以 property 必須在 data 對(duì)象上存在才能讓 Vue 將它轉(zhuǎn)換為響應(yīng)式的,這篇文章主要介紹了導(dǎo)致VUE頁面不刷新的問題分析及解決方法,需要的朋友可以參考下
    2024-04-04
  • Vue設(shè)置select下拉框的默認(rèn)選項(xiàng)詳解(select空白bug解決)

    Vue設(shè)置select下拉框的默認(rèn)選項(xiàng)詳解(select空白bug解決)

    最近開始學(xué)習(xí)vue,在學(xué)習(xí)的過程中遇到的問題將記錄在這里,下面這篇文章主要給大家介紹了關(guān)于Vue設(shè)置select下拉框的默認(rèn)選項(xiàng)(select空白bug解決)的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • VUE 實(shí)現(xiàn)一個(gè)簡(jiǎn)易老虎機(jī)的項(xiàng)目實(shí)踐

    VUE 實(shí)現(xiàn)一個(gè)簡(jiǎn)易老虎機(jī)的項(xiàng)目實(shí)踐

    老虎機(jī)在很多地方都可以見到,可以設(shè)置中獎(jiǎng)位置,以及中獎(jiǎng)回調(diào),本文主要介紹了VUE 實(shí)現(xiàn)一個(gè)簡(jiǎn)易老虎機(jī)的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 對(duì)Vue table 動(dòng)態(tài)表格td可編輯的方法詳解

    對(duì)Vue table 動(dòng)態(tài)表格td可編輯的方法詳解

    今天小編就為大家分享一篇對(duì)Vue table 動(dòng)態(tài)表格td可編輯的方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • vue實(shí)現(xiàn)input框禁止輸入標(biāo)簽

    vue實(shí)現(xiàn)input框禁止輸入標(biāo)簽

    這篇文章主要介紹了vue實(shí)現(xiàn)input框禁止輸入標(biāo)簽,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評(píng)論