Vue 3.0 升級紀錄
隨著 Vue 3.0 進入到 Beta 階段,而且官方也給出了預計在七月中旬發佈 RC (Release Candidate), 以及正式版即將在八月發佈的明確目標,相信已經有不少朋友都想試試 Vue 3.0 了吧?
最近也 超前部署 花了一點時間將工作專案從 Vue 2.6 升級上 Vue 3.0 Beta,
這篇就簡單做個記錄,以及分享一些升級過程可能會遇到的坑。
環境說明
為了確保避免開發環境造成的差異,這裡先列出我目前使用的開發環境:
$ node -v
v14.3.0
$ yarn -v
1.22.4
$ npm -v
6.14.5
$ vue -V
@vue/cli 4.4.6
起手式
首先你得要有個 Vue 2.x (當初是以 VueCLI 建置) 的專案,然後在專案目錄下執行
$ vue add vue-next
這個時候, Vue CLI 會自動安裝對應的套件。
看到這個畫面就代表套件升級完成了,升級後可以檢查你的 package.json
檔案以及相關的版本是否有正確更新。
掛載點的變更
如果你是用 CLI 預設的 main.js
作為進入點,那麼 Vue CLI 會自動將原本的
import Vue from 'vue'
改為
import { createApp } from 'vue';
原本的掛載點
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
也會自動變成
createApp(App).use(router).use(store).mount('#app')
的新版語法。
如果你跟我一樣,使用的是多頁型的專案配置,那麼你會看到
Cannot find file src/main.js
的錯誤訊息。
不過沒關係,相關套件還是會升級,只是你得花點力氣人工手動將每一頁的進入點從 import vue from 'vue'
改成 import { createApp } from 'vue'
,
以及 new Vue({...})
改成 createApp(App).mount('XXX')
的寫法。
el
屬性不再適用,而掛載時的 mount
也無需再加上 $
了。
明顯的語法變動
多數的語法更新在執行 vue-cli-service lint
都會有提示。
這裡講一下更新時幾個明顯的語法變動。
首先是 filter
option 被移除,替代方式很簡單就是搬到 methods
來使用,然後將 template 的 pipe 語法改寫。
事件修飾子的 .native
被移除,更準確的說是不需要了。
讓我花最多時間改寫的其實是 EventBus 的部分。
由於 Vue 3.0 移除了事件處理的 $on
, $off
以及 $once
,
使得過去我們透過一個空的 Vue 實體來當作事件訂閱/傳遞的載體 (俗稱 EventBus),這樣的方式已經不再適用,
對於這個問題,我的建議是:直上 Vuex。 你終究要用到 Vuex 的。
當然也有其他方法硬幹,就不在這篇的討論範圍
原本 2.x 的 options API 還是可以用,不用擔心 Vue 3.0 之後都得改成 setup 開頭了。
取消 .sync
修飾子,新增多組 v-model
過去我們透過 prop
與 .sync
來同步上下層 component 狀態 (俗稱雙向綁定) 的方式,
現在可以改由多組 v-model
來做到了:
<my-reg-form
v-model:name="name"
v-model:email="email" />
<!-- myRegForm.vue -->
<template>
<input
:value="name"
@input="updateName($event.target.value)" />
<input
:value="email"
@input="updateEmail($event.target.value)" />
</template>
<script>
export default {
props: {
name: String,
email: String
},
setup (props, { emit }) {
const updateName = value => {
emit('update:name', value)
}
const updateEmail = value => {
emit('update:email', value)
}
return {
updateName,
updateEmail
}
}
}
</script>
scoped styles 的改寫
CSS 的部分,原本我們為了將樣式穿透至子元素,會使用 /deep/
或 >>>
的語法來處理,未來需要改成 ::v-deep()
的形式:
/* 即將廢棄 */
::v-deep .bar {}
/* Vue 3.0 的寫法 */
::v-deep(.bar) {}
並且新增了一個 ::v-global
的 pseudo element,可以用在 style scoped
的範圍下。
Vuex 的變動
既然講到 Vuex,那麼 Vuex 升級後有沒有什麼要注意的地方?
有的,將原本的
import Vuex from 'vuex'
export default new Vuex.Store({ ... })
改成
import { createStore } from 'vuex'
export default createStore({ ... })
就這樣,沒了。
其他
最後是 webpack 或 vue.config.js
的 alias
需要改成 vue$: 'vue/dist/vue.esm-bundler.js'
,否則 CLI 會告訴你他找不到 Vue,一直要你重裝。
目前升級 Vue 3.0 的開發體驗相當好,像是大家都很熟悉的 composition api、直接在 component 使用 v-model
,
以及新增的 async-component 與 <Suspense>
等等,都是非常實用的功能。
缺點是截至目前還沒有 devtool 可以用,得憑經驗通靈。 聽說 RC 出來的時候就會有了 XD
工商服務
這篇只是記錄一下升級遇到的幾個問題。
如果你對 Vue 3.0 新增的部分也有興趣,剛好我在五倍紅寶石八月份有開設一門 Vue.js 與 Vuex 前端開發實戰課程, 教材已經更新至 3.0 (當然 2.x 也適用),歡迎你來參加。
參考資料與相關連結: