国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue2響應(yīng)式原理----發(fā)布訂閱模式

這篇具有很好參考價(jià)值的文章主要介紹了vue2響應(yīng)式原理----發(fā)布訂閱模式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

很多人感覺vue2的響應(yīng)式其實(shí)用到了觀察者+發(fā)布訂閱。我們先來看一下簡(jiǎn)單的發(fā)布訂閱的代碼:

// 調(diào)度中心
class Dep {
    static subscribes = {}
    // 訂閱所有需求
    static subscribe (key, demand) {
      // 對(duì)需求分類收集
      if (!Dep.subscribes[key]) Dep.subscribes[key] = []
      Dep.subscribes[key].push(demand)
    }
    // 對(duì)所有訂閱者發(fā)布通知
    static publish (key, age) {
      if (!Dep.subscribes[key]) return
      for (const demand of Dep.subscribes[key]) {
        demand(age)
      }
    }
  }
  // 找對(duì)象的獵手類
  class Watcher {
    constructor (name, age) {
      this.name = name // 名字
      this.age = age // 年齡
    }
    // 訂閱,由調(diào)度中心將獵手需求分類并存放到全局
    subscribe (key, demand) {
      Dep.subscribe(key, demand)
    }
    // 發(fā)布,由調(diào)度中心將同分類下的需求全部觸發(fā)
    publish (key, age) {
      Dep.publish(key, age)
    }
  }
  // 獵手注冊(cè)
  const aa = new Watcher('aa', 18)
  const bb = new Watcher('bb', 20)
  // 獵手訂閱自己感興趣的人
  aa.subscribe('key', function (age) {
    if (age === aa.age) console.log(`我是aa,我們都是${age}`)
    else console.log(`我是aa,我們年齡不同`)
  })
  bb.subscribe('key', function (age) {
    if (age === bb.age) console.log(`我是bb,我們都是${age}`)
    else console.log(`我是bb,我們年齡不同`)
  })
  // 紅娘注冊(cè)
  const red = new Watcher('red', 35)
  // 紅娘發(fā)布信息
  red.publish('key', 20)
  // 我是aa,我們年齡不同
  // 我是bb,我們都是20

從上面中發(fā)現(xiàn)一個(gè)重要的點(diǎn),發(fā)布者和訂閱者是根據(jù)key值來區(qū)分的,然后通過消息中心來中轉(zhuǎn)的,他們家是是實(shí)現(xiàn)不知道對(duì)方是誰(shuí)。
而觀察者模式中觀察者是一開始就知道自己觀察的是誰(shuí)。

上面其實(shí)就是簡(jiǎn)易版的vue原理中發(fā)布訂閱那段,我們接下來看完整過程。

Vue2 的響應(yīng)式

  1. 創(chuàng)建一個(gè) Observer 對(duì)象,它的主要作用是給對(duì)象的每個(gè)屬性添加 getter 和 setter 方法。
  2. 在 getter 和 setter 方法中分別進(jìn)行依賴的收集和派發(fā)更新。
  3. 創(chuàng)建 Watcher 對(duì)象,用于監(jiān)聽數(shù)據(jù)的變化,當(dāng)數(shù)據(jù)發(fā)生任何變化時(shí),Watcher 對(duì)象會(huì)觸發(fā)自身的回調(diào)函數(shù)。
  4. 在模板解析階段,對(duì)模板中使用到的數(shù)據(jù)進(jìn)行依賴的收集,即收集 Watcher 對(duì)象。
  5. 當(dāng)數(shù)據(jù)發(fā)生變化時(shí),Observer 對(duì)象會(huì)通知 Dep 對(duì)象調(diào)用 Watcher 對(duì)象的回調(diào)函數(shù)進(jìn)行更新操作,即派發(fā)更新。
  6. 更新完畢后,Vue2 會(huì)進(jìn)行視圖的重新渲染,從而實(shí)現(xiàn)響應(yīng)式。

下面是一個(gè)基于 Object.defineProperty 實(shí)現(xiàn)響應(yīng)式的示例,僅供參考:

function observe(obj) {
  if (!obj || typeof obj !== 'object') {
    return;
  }
  Object.keys(obj).forEach(key => {
    // 嘗試遞歸處理
    observe(obj[key]);
    let val = obj[key];
    const dep = new Dep(); // 新建一個(gè)依賴
    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(); // 派發(fā)更新
      }
    });
  });
}
 
// 依賴類
class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
  }
  removeSub(sub) {
    const index = this.subs.indexOf(sub);
    if (index !== -1) {
      this.subs.splice(index, 1);
    }
  }
  depend() {
    if (Dep.target) {
      Dep.target.addDep(this);
    }
  }
  notify() {
    this.subs.forEach(sub => sub.update());
  }
}
 
Dep.target = null;
 
// 觀察者類
class Watcher {
  constructor(vm, expOrFn, callback) {
    this.vm = vm;
    this.getter = parsePath(expOrFn);
    this.callback = callback;
    this.value = this.get(); // 初始化,觸發(fā)依賴
  }
  get() {
    Dep.target = this; // 設(shè)置當(dāng)前依賴
    const value = this.getter.call(this.vm, this.vm); // 觸發(fā) getter
    Dep.target = null; // 清除當(dāng)前依賴
    return value;
  }
  addDep(dep) {
    dep.addSub(this);
  }
  update() {
    const oldValue = this.value;
    this.value = this.get(); // 重新獲取
    this.callback.call(this.vm, this.value, oldValue); // 觸發(fā)回調(diào)
  }
}
 
// 解析路徑
function parsePath(expOrFn) {
  if (typeof expOrFn === 'function') {
    return expOrFn;
  }
  const segments = expOrFn.split('.');
  return function(obj) {
    for (let i = 0; i < segments.length; i++) {
      if (!obj) {
        return;
      }
      obj = obj[segments[i]];
    }
    return obj;
  };
}
 
// 測(cè)試
const obj = { foo: 'foo', bar: { a: 1 } };
observe(obj);
new Watcher(obj, 'foo', (val, oldVal) => {
  console.log(`foo changed from ${oldVal} to ${val}`);
});
new Watcher(obj, 'bar.a', (val, oldVal) => {
  console.log(`bar.a changed from ${oldVal} to ${val}`);
});
 
obj.foo = 'FOO'; // 輸出 `foo changed from foo to FOO`
obj.bar.a = 2; // 輸出 `bar.a changed from 1 to 2`

以上代碼中,函數(shù) observe 用于遞歸遍歷對(duì)象屬性,把其進(jìn)行劫持,包括收集依賴和派發(fā)更新;類 Dep 代表一個(gè)依賴,其中 addSub 用于添加訂閱者實(shí)例,removeSub 用于移除訂閱者實(shí)例,depend 用于收集依賴,即把當(dāng)前依賴加到對(duì)應(yīng)的訂閱者中,notify 用于派發(fā)更新,即遍歷所有訂閱者,并觸發(fā)其回調(diào)函數(shù)。類 Watcher 則代表一個(gè)訂閱者,其中 getter 用于獲取數(shù)據(jù),callback 用于回調(diào)函數(shù),addDep 用于添加依賴,即把當(dāng)前訂閱者添加到對(duì)應(yīng)的依賴中,update 用于更新值,并觸發(fā)相應(yīng)的回調(diào)函數(shù),如有必要。函數(shù) parsePath 則用于解析路徑字符串,返回對(duì)應(yīng)屬性的值。

例子中我們對(duì)對(duì)象 obj 進(jìn)行了劫持,同時(shí)創(chuàng)建了兩個(gè)觀察者,分別對(duì)應(yīng) foo 和 bar.a 兩個(gè)屬性。當(dāng)其中任意一個(gè)屬性的值發(fā)生變化時(shí),其對(duì)應(yīng)的依賴都會(huì)被更新,從而觸發(fā)其綁定的觀訂閱者的回調(diào)函數(shù)。

簡(jiǎn)單來說,在 Vue2 響應(yīng)式系統(tǒng)中,當(dāng)數(shù)據(jù)發(fā)生改變時(shí),會(huì)觸發(fā) get 和 set 方法,get 方法會(huì)收集所有依賴該數(shù)據(jù)的 Watcher 對(duì)象,set 方法會(huì)通知 Dep 對(duì)象觸發(fā)所有 Watcher 對(duì)象的回調(diào)函數(shù)進(jìn)行更新。如此循環(huán),實(shí)現(xiàn)了數(shù)據(jù)的響應(yīng)式。

vue2響應(yīng)式原理----發(fā)布訂閱模式,vue,前端,js,前端,javascript,開發(fā)語(yǔ)言文章來源地址http://www.zghlxwxcb.cn/news/detail-851318.html

到了這里,關(guān)于vue2響應(yīng)式原理----發(fā)布訂閱模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • js設(shè)計(jì)模式:發(fā)布訂閱模式

    js設(shè)計(jì)模式:發(fā)布訂閱模式

    也稱之為消息隊(duì)列模式,或者pubsub模式 發(fā)布者發(fā)布消息(也可以理解為調(diào)用某函數(shù)),訂閱者會(huì)收到消息,并且發(fā)布者可以將一些參數(shù)傳遞給訂閱者。 是一種常用的參數(shù)傳遞方法,經(jīng)典的pubsub.js,vue2中的$bus等都是用的這種模式。

    2024年02月19日
    瀏覽(83)
  • js設(shè)計(jì)模式——發(fā)布訂閱模式

    一、概述 發(fā)布訂閱模式是一種常用的設(shè)計(jì)模式,它定義了一種一對(duì)多的關(guān)系,讓多個(gè)訂閱者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象,當(dāng)主題對(duì)象發(fā)生變化時(shí),它會(huì)通知所有訂閱者對(duì)象,使它們能夠自動(dòng)更新 。 二、優(yōu)缺點(diǎn) 1. 優(yōu)點(diǎn): 實(shí)現(xiàn)了發(fā)布者和訂閱者之間的解耦,提高了代碼的可

    2024年02月06日
    瀏覽(89)
  • 前端開發(fā)攻略---從源碼角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章讓你徹底弄懂響應(yīng)式原理。

    前端開發(fā)攻略---從源碼角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章讓你徹底弄懂響應(yīng)式原理。

    Vue的響應(yīng)式到底要干什么? 無非就是要知道當(dāng)你 讀取 對(duì)象的時(shí)候,要知道它讀了。要做一些別的事情 無非就是要知道當(dāng)你 修改 對(duì)象的時(shí)候,要知道它改了。要做一些別的事情 所以要想一個(gè)辦法, 把讀取和修改的動(dòng)作變成一個(gè)函數(shù) ,讀取和修改的時(shí)候分別調(diào)用對(duì)應(yīng)的函數(shù)

    2024年04月17日
    瀏覽(35)
  • js 中單例模式、工廠模式、裝飾模式、發(fā)布訂閱模式、適配器模式、

    簡(jiǎn)單概述:將每個(gè)功能拆分到最小化,最后將小功能拼接到一起

    2024年02月11日
    瀏覽(61)
  • Vue2-全局事件總線、消息的訂閱與發(fā)布、TodoList的編輯功能、$nextTick、動(dòng)畫與過渡

    Vue2-全局事件總線、消息的訂閱與發(fā)布、TodoList的編輯功能、$nextTick、動(dòng)畫與過渡

    ??:高度自律即自由 更多Vue知識(shí)請(qǐng)點(diǎn)擊——Vue.js 一種組件間通信的方式,適用于任意組件間通信。通俗理解就是一個(gè)定義在所有組件之外的公共嘎達(dá),這個(gè)嘎達(dá)可以有vm或vc上的同款 $on、$off、$emit ,也可以讓所有組件都訪問到。要想實(shí)現(xiàn)這個(gè)事情,只能在 Vue.prototype 上添加

    2024年02月11日
    瀏覽(18)
  • Vue2.0 的響應(yīng)式原理 私

    Vue2.0 的響應(yīng)式原理 私

    使用的Object.defineProperty()重新定義對(duì)象,給data的每個(gè)屬性都添加了getter和setter方法。這時(shí)候會(huì)為對(duì)象的每個(gè)屬性創(chuàng)建一個(gè)Dep實(shí)例? (依賴)。Dep實(shí)例可以訂閱和通知相關(guān)的Watcher實(shí)例。,? 這一步叫? 數(shù)據(jù)劫持? 或者 依賴收集 在數(shù)據(jù)發(fā)生更新后調(diào)用 set 時(shí)會(huì)通知發(fā)布者 notify

    2024年02月11日
    瀏覽(19)
  • 從Vue層面 - 解析發(fā)布訂閱模式和觀察者模式區(qū)別

    從Vue層面 - 解析發(fā)布訂閱模式和觀察者模式區(qū)別

    觀察者模式和發(fā)布訂閱模式作為日常開發(fā)中經(jīng)常使用到的模式,我一直不能做到很好的區(qū)分。最近在看Vue的源碼,里面設(shè)計(jì)到了觀察者模式,比較感興趣,就去學(xué)習(xí)了下,這里做個(gè)總結(jié)吧。 基于一個(gè) 事件中心 ,接收通知的對(duì)象是訂閱者,需要先訂閱某個(gè)事件,觸發(fā)事件的對(duì)

    2024年02月15日
    瀏覽(90)
  • 202 vue2的響應(yīng)式原理 通俗易懂!

    Object.defineProperty + 依賴追蹤 。 在Vue實(shí)例化過程中,會(huì) 遞歸 地將 每個(gè)數(shù)據(jù)對(duì)象 的 屬性 轉(zhuǎn)換為 getter/setter ,并維護(hù)一個(gè) 依賴收集器(Dep) 。 每個(gè)屬性 都有一個(gè)關(guān)聯(lián)的 watcher ,當(dāng) 數(shù)據(jù)發(fā)生 變化時(shí) , watcher 會(huì) 被通知 并 更新視圖 。 Vue 2.x 實(shí)現(xiàn)響應(yīng)式數(shù)據(jù): vue實(shí)例化 時(shí),會(huì)

    2024年02月06日
    瀏覽(30)
  • Vue2和Vue3響應(yīng)式原理實(shí)現(xiàn)的核心

    Vue.js 是一個(gè)開源的漸進(jìn)式 JavaScript 前端框架,主要用于構(gòu)建用戶界面和單頁(yè)應(yīng)用程序(SPA)。Vue.js 可以輕松地與其他庫(kù)或現(xiàn)有項(xiàng)目集成使用,并被認(rèn)為是開發(fā)響應(yīng)式數(shù)據(jù)驅(qū)動(dòng)的現(xiàn)代 Web 應(yīng)用的一種有效方式。 Vue.js 的核心特點(diǎn): 響應(yīng)式數(shù)據(jù)綁定:Vue.js 可以通過對(duì)數(shù)據(jù)進(jìn)行雙

    2024年02月08日
    瀏覽(40)
  • 從Vue2到Vue3【七】——Vue2中響應(yīng)式原理的實(shí)現(xiàn)及其缺陷

    從Vue2到Vue3【七】——Vue2中響應(yīng)式原理的實(shí)現(xiàn)及其缺陷

    內(nèi)容 鏈接 從Vue2到Vue3【零】 Vue3簡(jiǎn)介 從Vue2到Vue3【一】 Composition API(第一章) 從Vue2到Vue3【二】 Composition API(第二章) 從Vue2到Vue3【三】 Composition API(第三章) 從Vue2到Vue3【四】 Composition API(第四章) 從Vue2到Vue3【五】 新的組件(Fragment、Teleport、Suspense) 從Vue2到Vue3【六

    2024年02月15日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包