日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

再也不怕面試官問watch、computed、watchEffect的區別了

來源: 責編: 時間:2023-11-30 09:30:28 249觀看
導讀在Vue中,數據響應式是一個核心概念,它使得當數據變化時,相關的視圖會自動更新。為了更靈活地處理數據的變化,Vue提供了多種方式,其中包括watch、computed和watchEffect。watchwatch是Vue中一個非常強大的特性,它允許你監聽

在Vue中,數據響應式是一個核心概念,它使得當數據變化時,相關的視圖會自動更新。為了更靈活地處理數據的變化,Vue提供了多種方式,其中包括watch、computed和watchEffect。Jj428資訊網——每日最新資訊28at.com

watch

watch是Vue中一個非常強大的特性,它允許你監聽數據的變化并做出相應的反應。它有兩種用法:一是監聽一個具體的數據變化,二是監聽多個數據的變化。Jj428資訊網——每日最新資訊28at.com

// 監聽單個數據watch('someData', (newVal, oldVal) => {  // 做一些事情});// 監聽多個數據watch(['data1', 'data2'], ([newVal1, newVal2], [oldVal1, oldVal2]) => {  // 做一些事情});

watch的實現原理

Vue中watch的實現主要依賴于Watcher這個核心類。當調用watch時,實際上是創建了一個Watcher實例,并將回調函數和需要監聽的數據傳遞給這個實例。Jj428資訊網——每日最新資訊28at.com

// 簡化版的watch實現function watch(source, cb) {  const watcher = new Watcher(source, cb);}

Watcher類的構造函數接收兩個參數,分別是需要監聽的數據(可以是一個字符串,也可以是一個返回值的函數)和回調函數。在構造函數中,會對數據進行求值,然后將這個Watcher實例添加到數據的依賴列表中。Jj428資訊網——每日最新資訊28at.com

class Watcher {  constructor(source, cb) {    this.getter = typeof source === 'function' ? source : () => this.vm[source];    this.cb = cb;    this.value = this.get();  }  get() {    pushTarget(this); // 將當前Watcher實例壓棧    const value = this.getter.call(this.vm); // 觸發數據的getter,將當前Watcher實例添加到依賴列表中    popTarget(); // 將當前Watcher實例出棧    return value;  }  update() {    const oldValue = this.value;    this.value = this.get();    this.cb(this.value, oldValue);  }}

簡單來說,watch的實現原理就是通過Watcher實例來監聽數據的變化,當數據變化時,觸發update方法執行回調函數。Jj428資訊網——每日最新資訊28at.com

computed

computed用于計算派生數據。它依賴于其他響應式數據,并且只有在相關數據發生變化時才會重新計算。Jj428資訊網——每日最新資訊28at.com

computed(() => {  return someData * 2;});

computed的實現原理

computed的實現原理相對于watch更為復雜,它依賴于getter和setter的機制。在Vue中,computed的定義是一個包含get和set方法的對象。Jj428資訊網——每日最新資訊28at.com

const computed = {  get() {    return someData * 2;  },  set(value) {    someData = value / 2;  }};

在computed的實現中,當訪問計算屬性時,實際上是執行了get方法,而在數據變化時,會執行set方法。這里主要使用了Object.defineProperty這個JavaScript的特性。Jj428資訊網——每日最新資訊28at.com

function createComputedGetter() {  return function computedGetter() {    const value = getter.call(this); // 執行計算屬性的get方法    track(target, TrackOpTypes.GET, 'value'); // 添加依賴    return value;  };}function createComputedSetter() {  return function computedSetter(newValue) {    setter.call(this, newValue); // 執行計算屬性的set方法    trigger(target, TriggerOpTypes.SET, 'value'); // 觸發更新  };}function computed(getterOrOptions) {  const getter =     typeof getterOrOptions === 'function'      ? getterOrOptions      : getterOrOptions.get;  const setter = getterOrOptions.set;  const cRef = new ComputedRefImpl(    getter,    setter,    isFunction(getterOrOptions) || !getterOrOptions.get  );  return cRef;}class ComputedRefImpl {  // 構造函數  constructor(getter, setter, isReadonly) {    // ...    this.effect = effect(getter, {      lazy: true,      scheduler: () => {        if (!this._dirty) {          this._dirty = true;          triggerRef(this);        }      },    });  }  // ...}

在上述代碼中,createComputedGetter和createComputedSetter用于創建計算屬性的getter和setter。computed函數接收一個getter函數,并通過Object.defineProperty將getter和setter添加到計算屬性的引用對象中。Jj428資訊網——每日最新資訊28at.com

當計算屬性被訪問時,會觸發getter,此時會將當前計算屬性添加到依賴列表中。當計算屬性的依賴數據發生變化時,會觸發setter,并通過triggerRef觸發計算屬性的更新。Jj428資訊網——每日最新資訊28at.com

watchEffect

watchEffect是Vue 3新增的特性,它用于監聽一個函數內部的響應式數據變化,當變化時,函數會被重新執行。Jj428資訊網——每日最新資訊28at.com

watchEffect(() => {  // 依賴于響應式數據的操作});

watchEffect的實現原理

watchEffect是Vue 3中引入的響應式API,它用于執行一個響應式函數,并在函數中響應式地追蹤其依賴。與watch不同,watchEffect不需要顯式地指定依賴,它會自動追蹤函數內部的響應式數據,并在這些數據變化時觸發函數重新執行。Jj428資訊網——每日最新資訊28at.com

以下是watchEffect的簡單用法:Jj428資訊網——每日最新資訊28at.com

import { watchEffect, reactive } from 'vue';const state = reactive({  count: 0,});watchEffect(() => {  console.log(state.count);});

在這個例子中,watchEffect內部的函數會自動追蹤state.count的變化,并在其變化時觸發函數執行。Jj428資訊網——每日最新資訊28at.com

現在,讓我們來探討watchEffect的實現原理。Jj428資訊網——每日最新資訊28at.com

首先,watchEffect的核心是依賴追蹤和觸發。Vue 3中的響應式系統使用ReactiveEffect類來表示一個響應式的函數。Jj428資訊網——每日最新資訊28at.com

class ReactiveEffect {  constructor(fn, scheduler = null) {    // ...    this.deps = [];    this.scheduler = scheduler;  }  run() {    // 執行響應式函數    this.active && this.getter();  }  stop() {    // 停止追蹤    cleanupEffect(this);  }}export function watchEffect(effect, options = {}) {  // 創建ReactiveEffect實例  const runner = effect;  const job = () => {    if (!runner.active) {      return;    }    if (cleanup) {      cleanup();    }    // 執行響應式函數    return runner.run();  };  // 執行響應式函數  job();  // 返回停止函數  return () => {    stop(runner);  };}

在上述代碼中,ReactiveEffect類表示一個響應式的函數。watchEffect函數接收一個響應式函數,并創建一個ReactiveEffect實例。在執行時,該實例會追蹤函數內部的響應式數據,并在這些數據變化時觸發函數重新執行。Jj428資訊網——每日最新資訊28at.com

watchEffect返回一個停止函數,用于停止對響應式數據的追蹤。Jj428資訊網——每日最新資訊28at.com

實際開發當中該怎么去選擇

watch

watch主要用于監聽特定的數據變化并執行回調函數。它可以監聽數據的變化,并在滿足一定條件時執行相應的操作。常見的使用場景包括:Jj428資訊網——每日最新資訊28at.com

  1. 異步操作觸發:當某個數據發生變化后,需要進行異步操作,比如發起一個網絡請求或執行一段耗時的操作。
watch(() => state.data, async (newData, oldData) => {  // 異步操作  await fetchData(newData);});
  1. 深度監聽:監聽對象或數組的變化,并在深層次的數據變化時執行回調。
watch(() => state.user.address.city, (newCity, oldCity) => {  console.log(`City changed from ${oldCity} to ${newCity}`);});

computed

computed用于創建一個計算屬性,它依賴于其他響應式數據,并且只有在依賴數據發生變化時才重新計算。常見的使用場景包括:Jj428資訊網——每日最新資訊28at.com

  1. 派生數據:根據現有的數據計算出一些派生的數據,而不必每次都重新計算。
const fullName = computed(() => `${state.firstName} ${state.lastName}`);
  1. 性能優化:避免不必要的重復計算,提高性能。
const result = computed(() => {  // 避免重復計算  if (someCondition) {    return heavyCalculation();  } else {    return defaultResult;  }});

watchEffect

watchEffect用于執行一個響應式函數,并在函數內部自動追蹤依賴。它適用于不需要顯式指定依賴,而是在函數內部自動追蹤所有響應式數據變化的場景。常見的使用場景包括:Jj428資訊網——每日最新資訊28at.com

  1. 自動依賴追蹤:函數內部的所有響應式數據都被自動追蹤,無需顯式指定。
watchEffect(() => {  console.log(`Count changed to ${state.count}`);});
  1. 動態數據處理:處理動態變化的數據,無需手動管理依賴。
watchEffect(() => {  // 處理動態變化的數據  handleDynamicData();});

總體而言,watch適用于需要有條件地監聽數據變化的場景,computed適用于創建派生數據和性能優化,而watchEffect適用于自動追蹤依賴的場景。在實際應用中,根據具體需求選擇合適的API可以更好地發揮Vue的響應式能力。Jj428資訊網——每日最新資訊28at.com


Jj428資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-35340-0.html再也不怕面試官問watch、computed、watchEffect的區別了

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 八股文-如何理解Java中的多態

下一篇: 再見,Shiro !你好,Sa-Token!

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 依兰县| 宝清县| 宁蒗| 白朗县| 清徐县| 瓮安县| 五河县| 五指山市| 德江县| 新民市| 始兴县| 桓台县| 衡东县| 绍兴市| 陵川县| 房产| 平罗县| 礼泉县| 乳山市| 沙河市| 彭州市| 准格尔旗| 神池县| 乌拉特后旗| 彭阳县| 吉林省| 瑞金市| 永仁县| 伊宁县| 德惠市| 河北区| 郎溪县| 梁平县| 清徐县| 西和县| 万州区| 普安县| 博爱县| 修武县| 祁连县| 渑池县|