<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 響應式系統 Vue.js 是一款 MVVM 框架,數據模型僅僅是普通的 JavaScript 對象,但是對這些對象進行操作時,卻能影響對應視圖,它的核心實現就是「**響應式系統**」。盡管我們在使用 Vue.js 進行開發時不會直接修改「**響應式系統**」,但是理解它的實現有助于避開一些常見的「**坑**」,也有助于在遇見一些琢磨不透的問題時可以深入其原理來解決它。 ## `Object.defineProperty` 首先我們來介紹一下 [`Object.defineProperty`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty),Vue.js就是基于它實現「**響應式系統**」的。 首先是使用方法: ``` /* obj: 目標對象 prop: 需要操作的目標對象的屬性名 descriptor: 描述符 return value 傳入對象 */ Object.defineProperty(obj, prop, descriptor) ``` descriptor的一些屬性,簡單介紹幾個屬性,具體可以參考 [MDN 文檔](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)。 * `enumerable`,屬性是否可枚舉,默認 false。 * `configurable`,屬性是否可以被修改或者刪除,默認 false。 * `get`,獲取屬性的方法。 * `set`,設置屬性的方法。 ## 實現 `observer`(可觀察的) 知道了 `Object.defineProperty` 以后,我們來用它使對象變成可觀察的。 這一部分的內容我們在第二小節中已經初步介紹過,在 `init` 的階段會進行初始化,對數據進行「**響應式化**」。 ![](https://img.kancloud.cn/c4/dd/c4dd695d1c4423aeb8ea55e67fff486d_828x336.gif) 為了便于理解,我們不考慮數組等復雜的情況,只對對象進行處理。 首先我們定義一個 `cb` 函數,這個函數用來模擬視圖更新,調用它即代表更新視圖,內部可以是一些更新視圖的方法。 ``` function cb (val) { /* 渲染視圖 */ console.log("視圖更新啦~"); } ``` 然后我們定義一個 `defineReactive` ,這個方法通過 `Object.defineProperty` 來實現對對象的「**響應式**」化,入參是一個 obj(需要綁定的對象)、key(obj的某一個屬性),val(具體的值)。經過 `defineReactive` 處理以后,我們的 obj 的 key 屬性在「讀」的時候會觸發 `reactiveGetter` 方法,而在該屬性被「寫」的時候則會觸發 `reactiveSetter` 方法。 ``` function defineReactive (obj, key, val) { Object.defineProperty(obj, key, { enumerable: true, /* 屬性可枚舉 */ configurable: true, /* 屬性可被修改或刪除 */ get: function reactiveGetter () { return val; /* 實際上會依賴收集,下一小節會講 */ }, set: function reactiveSetter (newVal) { if (newVal === val) return; cb(newVal); } }); } ``` 當然這是不夠的,我們需要在上面再封裝一層 `observer` 。這個函數傳入一個 value(需要「**響應式**」化的對象),通過遍歷所有屬性的方式對該對象的每一個屬性都通過 `defineReactive` 處理。(注:實際上 observer 會進行遞歸調用,為了便于理解去掉了遞歸的過程) ``` function observer (value) { if (!value || (typeof value !== 'object')) { return; } Object.keys(value).forEach((key) => { defineReactive(value, key, value[key]); }); } ``` 最后,讓我們用 `observer` 來封裝一個 Vue 吧! 在 Vue 的構造函數中,對 `options` 的 `data` 進行處理,這里的 `data` 想必大家很熟悉,就是平時我們在寫 Vue 項目時組件中的 `data` 屬性(實際上是一個函數,這里當作一個對象來簡單處理)。 ``` class Vue { /* Vue構造類 */ constructor(options) { this._data = options.data; observer(this._data); } } ``` 這樣我們只要 new 一個 Vue 對象,就會將 `data` 中的數據進行「**響應式**」化。如果我們對 `data` 的屬性進行下面的操作,就會觸發 `cb` 方法更新視圖。 ``` let o = new Vue({ data: { test: "I am test." } }); o._data.test = "hello,world."; /* 視圖更新啦~ */ ``` 至此,響應式原理已經介紹完了,接下來讓我們學習「**響應式系統**」的另一部分 ——「**依賴收集**」。 注:本節代碼參考[《響應式系統的基本原理》](https://github.com/answershuto/VueDemo/blob/master/%E3%80%8A%E5%93%8D%E5%BA%94%E5%BC%8F%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86%E3%80%8B.js)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看