自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

同學(xué):談?wù)勀銓?duì) vue2 響應(yīng)式原理的理解

開(kāi)發(fā) 前端
Vue 2 的響應(yīng)式系統(tǒng)通過(guò)對(duì)象劫持、依賴(lài)收集、和更新通知機(jī)制來(lái)實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)視圖的更新。以下是實(shí)現(xiàn)的大致步驟。

Vue 2 的響應(yīng)式系統(tǒng)通過(guò)對(duì)象劫持、依賴(lài)收集、和更新通知機(jī)制來(lái)實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)視圖的更新。以下是實(shí)現(xiàn)的大致步驟(當(dāng)然具體的實(shí)現(xiàn)復(fù)雜得多):

一、對(duì)象劫持(Object.defineProperty)

1. 定義響應(yīng)式對(duì)象

使用 Object.defineProperty 對(duì)對(duì)象的每個(gè)屬性進(jìn)行劫持。Vue 2 會(huì)為每個(gè)屬性定義 getter 和 setter,以便在屬性被訪問(wèn)或修改時(shí)觸發(fā)相應(yīng)的邏輯。

function defineReactive(obj, key, val) {
  const dep = new Dep(); // 用于管理依賴(lài)

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      if (Dep.target) {
        dep.addSub(Dep.target); // 添加當(dāng)前 watcher 作為依賴(lài)
      }
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // 通知所有依賴(lài)更新
    }
  });
}

2. 遞歸劫持嵌套對(duì)象

如果屬性的值是對(duì)象,Vue 2 需要遞歸地將這些對(duì)象轉(zhuǎn)化為響應(yīng)式對(duì)象。通過(guò)遍歷對(duì)象的所有屬性來(lái)實(shí)現(xiàn)。

function observe(value) {
  if (!value || typeof value !== 'object') return;
  return new Observer(value);
}

class Observer {
  constructor(value) {
    this.value = value;
    this.walk(value);
  }

  walk(obj) {
    Object.keys(obj).forEach(key => defineReactive(obj, key, obj[key]));
  }
}

二、依賴(lài)收集與通知

1. 依賴(lài)管理(Dep 類(lèi))

Dep 類(lèi)用于管理所有依賴(lài)(即 Watcher 實(shí)例)。每當(dāng)一個(gè)屬性被訪問(wèn)時(shí),它會(huì)將當(dāng)前 Watcher 實(shí)例添加到依賴(lài)列表中。當(dāng)屬性值變化時(shí),Dep 會(huì)通知所有依賴(lài)進(jìn)行更新。

class Dep {
  constructor() {
    this.subs = [];
  }

  addSub(sub) {
    this.subs.push(sub);
  }

  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

2. Watcher 類(lèi)

Watcher 類(lèi)是 Vue 2 響應(yīng)式系統(tǒng)的核心。它用于接收數(shù)據(jù)變化通知并更新視圖。

class Watcher {
  constructor(updateFn) {
    this.update = updateFn;
    Dep.target = this;
    // 觸發(fā) getter 以便收集依賴(lài)
    this.value = this.get();
    Dep.target = null;
  }

  get() {
    // 訪問(wèn)數(shù)據(jù)屬性觸發(fā) getter
  }

  update() {
    // 數(shù)據(jù)變化時(shí)的處理邏輯
    this.get();
  }
}

三、計(jì)算屬性與偵聽(tīng)器

、1. 計(jì)算屬性(Computed Properties)

計(jì)算屬性是基于響應(yīng)式數(shù)據(jù)的緩存值。Vue 2 會(huì)自動(dòng)緩存計(jì)算屬性的結(jié)果,直到它依賴(lài)的響應(yīng)式數(shù)據(jù)發(fā)生變化。

computed: {
  doubledValue() {
    return this.value * 2;
  }
}

在實(shí)現(xiàn)上,計(jì)算屬性會(huì)創(chuàng)建一個(gè)專(zhuān)門(mén)的 Watcher 實(shí)例,并在依賴(lài)的屬性發(fā)生變化時(shí)重新計(jì)算其值。

2. 偵聽(tīng)器(Watchers)

偵聽(tīng)器用于觀察數(shù)據(jù)變化并執(zhí)行指定的回調(diào)函數(shù)。

watch: {
  value(newValue, oldValue) {
    // 當(dāng) value 發(fā)生變化時(shí)執(zhí)行的邏輯
  }
}

四、模板編譯

Vue 2 的模板編譯過(guò)程將模板轉(zhuǎn)換成渲染函數(shù),并利用響應(yīng)式系統(tǒng)來(lái)實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)的視圖更新。渲染函數(shù)會(huì)訪問(wèn)組件的數(shù)據(jù)屬性,觸發(fā)依賴(lài)收集和視圖更新。

function compileTemplate(template) {
  // 編譯模板為渲染函數(shù)
  return function render() {
    // 渲染邏輯
  };
}

在渲染過(guò)程中,模板中的數(shù)據(jù)綁定會(huì)觸發(fā)屬性的 getter,自動(dòng)收集依賴(lài)。當(dāng)數(shù)據(jù)變化時(shí),Watcher 會(huì)重新計(jì)算并更新視圖。

五、響應(yīng)式數(shù)據(jù)的訪問(wèn)與更新

1. 訪問(wèn)數(shù)據(jù)

當(dāng)訪問(wèn)一個(gè)響應(yīng)式屬性時(shí),getter 會(huì)被觸發(fā),當(dāng)前的 Watcher 會(huì)被添加到依賴(lài)列表中。

function get() {
  // 訪問(wèn)數(shù)據(jù)屬性觸發(fā) getter
  return this.value;
}

2. 更新數(shù)據(jù)

當(dāng)設(shè)置響應(yīng)式屬性的值時(shí),setter 會(huì)被觸發(fā),更新數(shù)據(jù)并通知所有依賴(lài)進(jìn)行更新。

function set(newVal) {
  if (newVal !== this.value) {
    this.value = newVal;
    this.dep.notify(); // 通知所有依賴(lài)
  }
}

總結(jié)

  • 對(duì)象劫持:通過(guò) Object.defineProperty 劫持對(duì)象的屬性,實(shí)現(xiàn)對(duì)屬性的讀寫(xiě)操作的攔截。
  • 遞歸劫持:遞歸地將嵌套對(duì)象轉(zhuǎn)化為響應(yīng)式對(duì)象。
  • 依賴(lài)管理:Dep 類(lèi)用于管理和通知依賴(lài)。
  • 計(jì)算屬性與偵聽(tīng)器:緩存計(jì)算屬性,利用偵聽(tīng)器響應(yīng)數(shù)據(jù)變化。
  • 模板編譯:將模板編譯為渲染函數(shù),自動(dòng)更新視圖。

這些細(xì)節(jié)使 Vue 2 能夠高效地實(shí)現(xiàn)雙向數(shù)據(jù)綁定和響應(yīng)式更新,確保視圖和數(shù)據(jù)的一致性。

責(zé)任編輯:趙寧寧 來(lái)源: 前端歷險(xiǎn)記
相關(guān)推薦

2022-08-26 00:02:03

RocketMQ單體架構(gòu)MQ

2024-09-20 05:46:00

2024-09-11 16:49:55

2019-07-01 13:34:22

vue系統(tǒng)數(shù)據(jù)

2022-08-14 07:14:50

Kafka零拷貝

2022-06-30 09:10:33

NoSQLHBaseRedis

2023-11-28 12:25:02

多線程安全

2022-09-06 11:13:16

接口PipelineHandler

2022-09-23 11:00:27

KafkaZookeeper機(jī)制

2022-03-29 09:59:58

響應(yīng)式系統(tǒng)Vue2

2022-04-03 19:27:35

Vue2響應(yīng)式系統(tǒng)

2022-08-29 16:03:33

狀態(tài)流轉(zhuǎn)Java

2022-04-06 07:28:47

數(shù)組響應(yīng)式系統(tǒng)

2022-04-02 09:56:41

Vue2響應(yīng)式系統(tǒng)

2022-04-14 08:46:46

響應(yīng)式系統(tǒng)js

2022-09-19 07:57:59

云服務(wù)互聯(lián)網(wǎng)基礎(chǔ)設(shè)施

2022-03-31 10:15:10

分支切換響應(yīng)式系統(tǒng)

2022-10-09 15:18:31

SwaggerOpenAPI工具

2022-09-09 10:15:06

OAuthJava

2022-04-10 11:04:40

響應(yīng)式系統(tǒng)setdelete
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)