天天看點

Vue.js 2 vs Vue.js 3的實作 – 雲栖社群Vue.js 2 vs Vue.js 3的實作 – 雲栖社群

Vue.js 2 vs Vue.js 3的實作 – 雲栖社群

Vue.js 2 vs Vue.js 3的實作 – 雲栖社群Vue.js 2 vs Vue.js 3的實作 – 雲栖社群

vue.js核心團隊已經讨論過将在Vue3實作的變化。雖然API不會改變,但是資料響應機制(譯者注:對資料改變的監聽和通知)發生了變化。這意味着什麼呢,同時它對你意味着什麼呢?

Vue 2 實作

Vue.js 2 中是通過在

Object.defineProperty

方法中定義的getters和setters來實作資料響應的。我們看下Vue的響應機制簡化版。

Object.defineProperty(obj, key, {    
    enumerable: true,
    configurable: true,
    get:function(){
       return value;
    },
    set:function(newValue){
        if(value !== newValue){
           value = newValue;
           tellTheWorldIhaveChanged(); //somebody is watching!
        }
    }
});
           

使用這種類型的設定,每當我們改變屬性,它會通知監聽者和依賴者,讓其知道這裡發生了變化。此屬性設定是在初始化模型和顯式調用

Vue.set

/

vm.$set

時發生的。

然而采用這種設定,以下這些操作需要額外的幫助:

  1. 數組按照索引進行更新
data(){
  return {
    names:[]
  }
}
...
this.persons[0] = 'John Elway';
           

你可能知道這不會觸發更新。事實上,

the holy guide of Vue

明确提到關于數組的警告。為什麼會這樣的呢?因為數組的setter沒辦法檢測到按照索引指派的操作。

解決它的一個辦法就是使用Vue.set

Vue.set(this.names, 0, 'John Elway');
           

不過,Vue已經封裝了

幾個數組方法

給我們,是以我們可以通過這些數組方法來更新我們的數組。

this.names.push('John Elway');
           

2. 動态添加屬性

data(){
  return {
    names:[]
  }
}

...

this.$data.lastAddedName = 'John Elway';
           

不是很好的例子,對嗎?這裡我可能提前知道這個屬性已經存在,但也有可能我們連屬性的名稱都不知道。JavaScript 松散的類型允許我們很輕易地添加屬性。然而Vue的響應機制并不知道我們添加了這個屬性。

讓我來拯救這一切! — Vue.set
Vue.set(this.$data,'lastAddedName','John Elway');
           
如果我們有辦法不用vue.set來解決這些問題,而是直接使用數組索引就好了。

Vue 3 實作

歡迎來到通過

代理(proxy)

實作的響應世界。代理是在ES6(又名ES2015)中引入的一個特性(是以其實它已經出現很久了)。由此,我很确定你已經了解它了,但可能無法在生産環境中使用它們。因為他們是沒有替代方法的。沒有polyfill,在舊浏覽器中無法用别的方式替代。

幸運地是,文法并不荒謬。事實上,這有點眼熟。

let data = {
   names:[]
};

data.names = new Proxy(data.names,{
    set:function(obj, prop, value){
            if(obj[prop] !== value){
                obj[prop] = value;
                tellTheWorldIhaveChanged();
            }
        }
});
           

這個代理不僅會捕捉我們前面提到的數組索引,而且當數組方法被調用時也會觸發。并且不需要包裝器。

動态添加屬性會怎樣?

data = new Proxy(data,{
    set:function(obj, prop, value){
            if(obj[prop] !== value){
                obj[prop] = value;
                tellTheWorldIhaveChanged();
            }
        }
});


data.lastAddedName = 'John Elway'; //tellTheWorldIhaveChanged()
           
天哪,真是太棒了。讓我們在Change.org上申請,快速建立一個吧!

總結

我在

即将釋出的2.5

版本之前不久寫的這篇文章。Vue 3沒有被談論很多,但我真的很期待上述提到的變化。也就是說,我不能在短期内在工作項目上使用它。為什麼?Vue 3不能用于Internet Explorer,并且Babel不能解決相容問題。

盡管存在相容性問題,采用新的響應機制有以下幾個長遠的好處。

  1. 簡化源 代碼— 這種改寫讓團隊對數組函數進行封裝,減少他們做類型檢查的次數。
  2. 新手容易學習 — 從響應機制中去掉之前版本裡的注意事項将有助于那些學習Vue的新手。論壇上關于數組響應性的一系列問題就會消失。
  3. 更好的性能* — 我聽說有些人認為這将加快響應系統的速度。但是它現在已經很快了,是以我還沒有完全接受這一觀點。

感謝閱讀!如果您發現任何錯誤,請讓我知道。

更新

據說這個使用代理的版本将在目前版本号後面添加 _ -next_ (就像esnext),而不是用“Vue 3”。此更新可能跟Vue 2.6同時釋出。是以,将會發行Vue2.6和Vue 2.6-next。這将消除對API的困惑。

本文轉載自: 衆成翻譯 譯者: foreverjiangting 審校: huangxiaolu 連結: http://www.zcfy.cc/article/4369 原文: https://blog.cloudboost.io/reactivity-in-vue-js-2-vs-vue-js-3-dcdd0728dcdf

繼續閱讀