面試時被問到,那就趁機梳理一下 vue 的演進吧
vue2 比 vue1 的改進
生命周期
比如說 beforeCompile 移除, 使用 created 替代,compiled 移除,使用 mounted 替換等
語法
新數組語法 (value, index) in arr,並丟棄 $index 和 $key
過濾器廢棄,不再這樣寫 <p v-for="item in items | limitBy 10">{{ item }}</p>
,改而在方法里自己做好分割
圍繞 DOM 的實例方法移除,比如說 vm.$appendTo 移除
單向數據流思想引入
v-model 變為語法糖,本質上變成了 emit 了一個 input 事件,並且在本組件內觸發它的更新。
$dispatch 和 $broadcast 廢棄
引入 vdom 虛擬節點
解偶 HTML 依賴,從此可以渲染到 DOM 意外的平台上,比如說 SSR。
vue3 比 vue2 的改進
vue 3 源碼:https://github.com/vuejs/vue-next
使用了 proxy 替代 Object.defineProperty
目前,Vue 的反應系統是使用 Object.defineProperty 的 getter 和 setter。 但是,Vue 3 將使用 ES2015 Proxy 作為其觀察者機制。 這消除了以前存在的警告,使速度加倍,並節省了一半的內存開銷。
為了繼續支持 IE11,Vue 3 將發布一個支持舊觀察者機制和新 Proxy 版本的構建
而為什么使用 Proxy 替代 Object.defineProperty?Proxy 可以劫持整個對象,並返回一個新的對象。Proxy 不僅可以代理對象,還可以代理數組,還可以代理動態增加的屬性。節省內存,速度加倍。關於 Proxy API 參見 MDN
新增 hook api
注意 setup
<template>
<div>
<span>count is {{ count }}</span>
<span>plusOne is {{ plusOne }}</span>
<button @click="increment">count++</button>
</div>
</template>
<script>
import { value, computed, watch, onMounted } from 'vue'
export default {
setup() {
// reactive state
const count = value(0)
// computed state
const plusOne = computed(() => count.value + 1)
// method
const increment = () => { count.value++ }
// watch
watch(() => count.value * 2, val => {
console.log(`count * 2 is ${val}`)
})
// lifecycle
onMounted(() => {
console.log(`mounted`)
})
// expose bindings on render context
return {
count,
plusOne,
increment
}
}
}
</script>
使用 setup 的好處都有啥?詳細參見尤雨溪 - 聊聊 Vue.js 3.0 Beta 官方直播完整版 2020-04-21,摘錄幾點
- 便於 tree shaking。像是 transition 這樣的代碼,如果你沒有使用到,它就會被 tree shaking,函數式的引入便於計算它究竟有沒有被用到,而導出整個對象就沒辦法特意去掉某個不會使用的屬性。新的 vue 核心運行時壓縮后大概 10kb
- 便於混淆壓縮使 vue 更小。因為 setup 是函數式引入的,引入進來的變量可以隨意命名混淆成 a,b,c 這樣的簡短字符,而對象的屬性不能被混淆。
- 代碼組織更加清晰,不用再懼怕不知道哪里注入進來的 mixins 的屬性和方法,若是 react 也不用擔心不知道從哪里注入的 props 屬性。
讓 vue 更快的優化
像是重寫虛擬DOM,優化插槽生成,靜態樹提升,靜態屬性提升。詳見尤雨溪 - 聊聊 Vue.js 3.0 Beta 官方直播完整版 2020-04-21,本人也整理了一篇 vue 3.0 beta 編譯優化研究。簡言之,vue 3 已經能做到 diff 時,只對有變量的區域遍歷,靜態的節點直接復用對象不需要 diff。
其他支持
更好的ts支持,vue 3 直接用 ts 重寫。
總結
從用 vue 1.x 開始到現在 vue 3.x 登場,中間過去 4 年了吧,不知不覺 vue 都做了如此多的改進,若不是查了下資料我甚至都想不起來 vue 的 vdom 是在 vue 2.x 時引入的。