亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue中的Computed實(shí)現(xiàn)原理分析

 更新時(shí)間:2024年08月07日 09:55:26   作者:秦JaccLink  
這篇文章主要介紹了Vue中的Computed實(shí)現(xiàn)原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

在 Vue.js 中,computed 屬性是一種強(qiáng)大的特性,用于定義依賴于其他響應(yīng)式數(shù)據(jù)的計(jì)算值。

computed 屬性不僅能夠簡(jiǎn)化模板中的表達(dá)式,還能夠緩存計(jì)算結(jié)果,避免不必要的重復(fù)計(jì)算,從而提高性能。

將深入探討 Vue 中 computed 屬性的實(shí)現(xiàn)原理,包括其工作機(jī)制、依賴追蹤、緩存策略等方面。

1. Computed 屬性概述

Computed 屬性是 Vue 實(shí)例中的一個(gè)特殊屬性,它允許開發(fā)者定義一個(gè)計(jì)算值,該值依賴于其他響應(yīng)式數(shù)據(jù)。

Computed 屬性具有以下特點(diǎn):

  • 響應(yīng)式:當(dāng)依賴的數(shù)據(jù)發(fā)生變化時(shí),computed 屬性會(huì)自動(dòng)重新計(jì)算。
  • 緩存:computed 屬性會(huì)緩存計(jì)算結(jié)果,只有當(dāng)依賴的數(shù)據(jù)發(fā)生變化時(shí),才會(huì)重新計(jì)算。
  • 惰性求值:computed 屬性在首次訪問時(shí)才會(huì)進(jìn)行計(jì)算,之后會(huì)根據(jù)依賴數(shù)據(jù)的變化情況決定是否重新計(jì)算。

2. Computed 屬性的基本用法

在 Vue 實(shí)例中,可以通過 computed 選項(xiàng)來(lái)定義 computed 屬性。

new Vue({
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe'
    };
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  }
});

在上述代碼中,fullName 是一個(gè) computed 屬性,它依賴于 firstNamelastName。

當(dāng) firstNamelastName 發(fā)生變化時(shí),fullName 會(huì)自動(dòng)重新計(jì)算。

3. Computed 屬性的實(shí)現(xiàn)原理

3.1 依賴追蹤

Vue 的 computed 屬性實(shí)現(xiàn)依賴于 Vue 的響應(yīng)式系統(tǒng)。

Vue 通過 Object.definePropertyProxy 來(lái)劫持?jǐn)?shù)據(jù)的變化,并在數(shù)據(jù)變化時(shí)通知依賴該數(shù)據(jù)的觀察者。

3.1.1 響應(yīng)式數(shù)據(jù)劫持

Vue 在初始化數(shù)據(jù)時(shí),會(huì)通過 Object.definePropertyProxy 對(duì)數(shù)據(jù)進(jìn)行劫持,使其變?yōu)轫憫?yīng)式數(shù)據(jù)。

function defineReactive(obj, key, val) {
  const dep = new Dep();
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      if (Dep.target) {
        dep.depend();
      }
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify();
    }
  });
}

在上述代碼中,defineReactive 函數(shù)通過 Object.defineProperty 劫持了對(duì)象的屬性,并在 getset 方法中分別收集和通知依賴。

3.1.2 依賴收集

在 computed 屬性被訪問時(shí),Vue 會(huì)通過 Dep.target 來(lái)收集依賴。

functionWatcher(vm, expOrFn, cb) {
  this.vm = vm;
  this.getter = parsePath(expOrFn);
  this.cb = cb;
  this.value = this.get();
}

Watcher.prototype.get = function() {
  Dep.target = this;
  const value = this.getter.call(this.vm, this.vm);
  Dep.target = null;
  return value;
};

Watcher.prototype.update = function() {
  const oldValue = this.value;
  this.value = this.get();
  this.cb.call(this.vm, this.value, oldValue);
};

在上述代碼中,Watcher 實(shí)例在 get 方法中將自身設(shè)置為 Dep.target,然后訪問 computed 屬性,從而觸發(fā)依賴數(shù)據(jù)的 get 方法,完成依賴收集。

3.2 緩存策略

Computed 屬性具有緩存機(jī)制,只有在依賴數(shù)據(jù)發(fā)生變化時(shí),才會(huì)重新計(jì)算。

3.2.1 緩存實(shí)現(xiàn)

Vue 通過 Watcher 實(shí)例的 dirty 屬性來(lái)控制緩存。

function Watcher(vm, expOrFn, cb, options) {
  this.vm = vm;
  this.getter = expOrFn;
  this.cb = cb;
  this.dirty = this.lazy = !!options.lazy;
  this.value = this.lazy ? undefined : this.get();
}

Watcher.prototype.evaluate = function() {
  this.value = this.get();
  this.dirty = false;
};

Watcher.prototype.get = function() {
  pushTarget(this);
  let value;
  const vm = this.vm;
  try {
    value = this.getter.call(vm, vm);
  } finally {
    popTarget();
  }
  return value;
};

Watcher.prototype.update = function() {
  if (this.lazy) {
    this.dirty = true;
  } else {
    this.run();
  }
};

在上述代碼中,Watcher 實(shí)例的 dirty 屬性用于標(biāo)記 computed 屬性是否需要重新計(jì)算。

當(dāng)依賴數(shù)據(jù)發(fā)生變化時(shí),Watcherupdate 方法會(huì)將 dirty 設(shè)置為 true,表示需要重新計(jì)算。

3.2.2 惰性求值

Computed 屬性在首次訪問時(shí)才會(huì)進(jìn)行計(jì)算,之后會(huì)根據(jù) dirty 屬性決定是否重新計(jì)算。

function createComputedGetter(key) {
  return function computedGetter() {
    const watcher = this._computedWatchers && this._computedWatchers[key];
    if (watcher) {
      if (watcher.dirty) {
        watcher.evaluate();
      }
      if (Dep.target) {
        watcher.depend();
      }
      return watcher.value;
    }
  };
}

在上述代碼中,createComputedGetter 函數(shù)返回一個(gè) computed 屬性的 getter 函數(shù)。

在訪問 computed 屬性時(shí),如果 dirtytrue,則會(huì)調(diào)用 watcher.evaluate 方法進(jìn)行計(jì)算,并將 dirty 設(shè)置為 false,表示計(jì)算結(jié)果已緩存。

4. Computed 屬性的優(yōu)化

4.1 避免不必要的計(jì)算

在定義 computed 屬性時(shí),應(yīng)盡量避免不必要的計(jì)算。

例如,如果 computed 屬性的計(jì)算邏輯較為復(fù)雜,可以考慮將其拆分為多個(gè)簡(jiǎn)單的 computed 屬性。

computed: {
  fullName() {
    return `${this.firstName} ${this.lastName}`;
  },
  formattedName() {
    return this.fullName.toUpperCase();
  }
}

4.2 使用 Watcher 進(jìn)行性能優(yōu)化

在某些情況下,可以使用 watch 選項(xiàng)來(lái)替代 computed 屬性,以實(shí)現(xiàn)更細(xì)粒度的控制和性能優(yōu)化。

watch: {
  firstName: 'updateFullName',
  lastName: 'updateFullName'
},
methods: {
  updateFullName() {
    this.fullName = `${this.firstName} ${this.lastName}`;
  }
}

5. 總結(jié)

Vue 的 computed 屬性通過依賴追蹤和緩存策略,實(shí)現(xiàn)了響應(yīng)式計(jì)算和性能優(yōu)化。

在實(shí)現(xiàn)原理上,computed 屬性依賴于 Vue 的響應(yīng)式系統(tǒng),通過 Watcher 實(shí)例進(jìn)行依賴收集和緩存控制。

通過深入理解和掌握 computed 屬性的實(shí)現(xiàn)原理,開發(fā)者可以更好地利用這一特性,提高應(yīng)用的性能和可維護(hù)性。

在實(shí)際開發(fā)中,應(yīng)根據(jù)具體需求合理使用 computed 屬性,并結(jié)合其他優(yōu)化手段,如避免不必要的計(jì)算和使用 Watcher 進(jìn)行細(xì)粒度控制,從而構(gòu)建高效、穩(wěn)定的 Vue 應(yīng)用。

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

相關(guān)文章

最新評(píng)論