Vue3.0與Vue2.0的響應式對比

想必大多數人都被defineProperty的機制坑過,因此在Vue3.0即將到來之際,我作了一個Vue3.0與2.x的響應式效果的比對。沒有對比就沒有傷害,對比以後纔會知道3.0用了Proxy以後有多麼強大。javascript

打包

Vue3.0源碼倉庫 clone一份源碼。html

安裝

npm i
複製代碼

打包

npm run build
複製代碼

發現出錯了,ts的類型檢查有問題,更新一下 source-mapvue

npm i source-map
複製代碼

繼續打包,發現又出錯,仍是ts的類型錯誤,在transformExpression.ts這個文件中,把報錯的類型所有聲明爲any(反正咱們只是爲了打包),繼續打包java

此次打包成功了,生成的文件在packages/vue/dist目錄下,共有7個文件:git

  • vue.cjs.js
  • vue.cjs.prod.js
  • vue.esm-browser.js
  • vue.esm-browser.prod.js
  • vue.esm-bundler.js
  • vue.global.js
  • vue.global.prod.js

咱們選擇vue.global.prod.js,能夠在瀏覽器中直接使用github

準備示例代碼

建立文件

  1. 使用IDEA(WebStorm也同樣)建立一個空的項目
  2. 新建static文件夾(我的習慣)
  3. 在static文件夾下加入剛剛打包的Vue3.0的js文件以及Vue2的js文件
  4. 在static文件夾下分別建立Vue2.x和Vue3.x的測試文件 Vue2.x: index2.html, vue2.js Vue3.0: index3.html, vue3.js
  5. 建立一個可用於展現響應式特性的組件文件comp.js

這個時候,static下的文件結構是這樣的:shell

  • comp.js
  • index2.html
  • index3.html
  • vue.global.prod.js
  • vue.js
  • vue2.js
  • vue3.js

準備測試代碼

編寫html文件npm

index2.html內容以下:數組

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="./vue.js"></script>
</head>
<body>
  <div id="app"></div>
  <script src="./comp.js"></script>
  <script src="./vue2.js"></script>
</body>
</html>
複製代碼

index3.html瀏覽器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="./vue.global.prod.js"></script>
</head>
<body>
  <div id="app"></div>
  <script src="./comp.js"></script>
  <script src="./vue3.js"></script>
</body>
</html>
複製代碼

除了引用文件的不一樣沒有任何其餘的區別

編寫公共組件

const Comp = {
  template: ` <div> <h2>測試對象添加屬性</h2> <div>{{person}}</div> <div> <button @click="addProperty">添加屬性</button> <button @click="deleteProperty">刪除屬性age</button> </div> <h2>測試數組修改</h2> <div>{{array}}</div> <div> <button @click="addArrayItemProperty">添加元素0屬性</button> <button @click="deleteArrayItemProperty">刪除元素0屬性</button> <button @click="replaceArrayItem">替換元素1</button> </div> </div> `,
  data() {
    return {
      msg: 'abc',
      person: { name: 'aa', age: 22 },
      array: [{
        name: '1'
      }, {
        name: '2'
      }]
    };
  },
  methods: {
    addProperty() {
      this.msg = this.msg + '1';
      this.person[this.msg] = this.msg;
    },
    deleteProperty() {
      delete this.person.age;
    },
    addArrayItemProperty() {
      this.array[0].enname = 'abc';
    },
    deleteArrayItemProperty() {
      delete this.array[0].name;
    },
    replaceArrayItem() {
      this.array[1] = { name: '222' };
    }
  }
};
複製代碼

組件內的操做分別驗證的是:

  • 對象屬性添加
  • 對象屬性刪除
  • 對象數組內已存在元素的屬性添加
  • 對象數組內已存在元素的屬性刪除
  • 對象數組內已存在元素的替換(使用索引)

這裏有個小插曲,一開始我只是驗證3.0的響應式,因此編寫組件的時候template沒有用div包裹,直接聲明瞭多個根節點(也是無意插柳,畢竟不多直接寫瀏覽器渲染的組件),原本沒發現問題,結果一樣的組件用在2.x上的時候,提示我組件不能存在多個根節點...

編寫Vue3.0與2.x的入口文件

vue2.js

new Vue({
  el: '#app',
  template: '<Comp/>',
  components: {
    Comp: Comp
  }
});
複製代碼

vue3.js

const app = Vue.createApp();
app.mount(Comp, '#app');
複製代碼

事實顯示Vue3.0的入口編寫更爲簡便,不過這不是今天的主題,接下來就是見證的時刻:

在IDE中直接運行index2.html和index3.html

是否是一毛同樣?這裏發現一個小問題,Vue2.x渲染出來的內容,並排的button之間有間隙,而Vue3.0渲染的內容沒有。我審查元素髮現兩個頁面的源碼是一毛同樣的。這個若是有人知道爲何的話請告訴我一下。

接下來咱們依次點擊兩個頁面上的5個按鈕後看頁面的變化:

2.x

點完以後,海棠依舊,沒有任何的變化

3.0

內容發生變化,5個操做所有生效

結束語

此次的驗證到這裏就結束了,此次的驗證一方面是想盡快嘗試一下3.0的使用(等發佈不知道還要多久,估計還得幾個月,核心代碼還在開發,配套的工具估計在開發完以後還要一段時間),另外我寫了一個Vue的表單解決方案(沒有在掘金髮布過,只在公司內部使用),踩過defineProperty的很多坑,因此可能會提早開發適配3.0的版本。OK,讓咱們共同期待Vue3.0的正式發佈吧!

相關文章
相關標籤/搜索