該系列是為了讓看過Vue官方文件或學過Vue但是卻不知道怎麼下手去重構現在有的網站而去規畫的系列文章,在這邊整理了許多我自己使用Vue重構很多網站的經驗分享給讀者們。
Vue3 的 Composition API 一出來就引起來了許多寫 Vue 的工程師熱烈討論,但是如果今天你開發的專案是Vue2的專案,但是又不能說打掉重構,也不能隨便把 Vue2直接升級到 Vue3,但是真的很想體會 Composition API 帶來的好處以及優勢,那該怎麼辦?目前有兩個方法...
@vue/composition-api
的套件,可以讓 Vue 2.6.14 以下的版本使用 Composition API 的寫法,裝上了這個套件雖然 Vue 的底層還是 object.defineproperty
但是可以用 Composition API 來取代 mixin 處理共用邏輯。@vue/composition-api
的出現可以說是幫助那些無法升級或是工作上面只能維護舊專案的工程師,接觸一個全新的、未來的 Vuejs 主流的開發方式,而且載入專案一點也不困難,所以如果你的專案還是 Vue2 的情況下,我會建議你馬上把@vue/composition-api
安裝起來吧。
npm install @vue/composition-api
然後你只要這樣
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
就可以使用 Composition API 了,是不是非常間單。
@vue/composition-api 的 GitHub : https://github.com/vuejs/composition-api
import { ref, reactive, provide, inject, computed } from "@vue/composition-api";
我們要再 component 裡面要使用 Vue3 的語法的時候,就直接 import @vue/composition-api
就可以用了,基本上功能來說其實都差不多,雖然可以用 Composition API 去讓 Vue2 去支援 Composition API 的語法,但是其實還是有些 API 並沒有完全的支援,而且不可避免的是還有額外的效能消耗,除非是在非常極端的情況下,不然基本上應該沒有什麼問題,@vue/composition-api
已經非常好用了。
具體支援度的部分可以看一下文件上面寫的。
@vue/composition-api 的限制:https://github.com/vuejs/composition-api#limitations
之後未來真的要重構開一個 Vue3 環境的專案的時候,你就把 component 搬過去,@vue/composition-api
改成 vue 就好了。
不過這邊要特別注意一下,雖然可以使用 @vue/composition-api
來開發,但是專案的底還是 Vue2,所以使用像是 Vuex 、Vue-Router 的時候,引入的方式也都還是 Vue2 的使用方式。
Vuex4.x版本是這樣使用的
import { computed } from 'vue'
import { useStore } from 'vuex'
export default {
setup () {
const store = useStore()
const count = computed(() => store.state.count)
return {
count
}
}
}
但是 Vuex3.x 版本並沒有 useStore 這個方法,所以如果我們要讓我們的語法貼近 Vuex3.x 的話,教大家一個奧步
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
isLoad: false
},
mutations: {
increment (state) {
state.isLoad = !state.isLoad;
}
},
getters: {
isLoad: state => state.isLoad
}
})
// 奧步
export const useStore = () => store;
export default store;
我定義了一個 useStore
的函式去 return 原本的 store object。
這樣一來我要使用的時候我只要引入這個 store.js
就可以有一個名叫 useStore
的方法可以拿來用
<script>
import { computed } from "@vue/composition-api";
import { useStore } from "../../store";
export default {
setup() {
const store = useStore();
const isLosd = computed(() => store.getters["isLoad"]);
return {
isLosd,
};
},
}
</script>
<template>
<div>
<Loading v-show="isLosd" />
</div>
</template>
當以後要更新 Vuex 版本的時候,只要更新這段../../store
的路徑即可。
首先我們可以使用一個叫做 getCurrentInstance
的函式,我們先開一個 useRoute.js
的檔案。
useRoute.js
import { getCurrentInstance } from "@vue/composition-api";
export function useRoute() {
const vm = getCurrentInstance();
return { route: vm.proxy.$route, router: vm.proxy.$router, }
}
這邊我們去定義 useRoute
來模擬 Vue-Router v4.x
版本的寫法,getCurrentInstance
是可以取得到 Vue 的實體,所以我們可以把 $route
跟 $router
重新包起來。
接下來我們就可以直接來使用它。
<script>
import { useRoute } from "./useRoute.js";
export default {
setup() {
const { route, router } = useRoute();
console.log({ route, router});
const gotoPageAbout = () => {
router.push("about")
}
return {
gotoPageAbout,
}
},
};
</script>
所以一樣當我們今天升級版本的時候,再去替換掉就好,非常的方便。
目前使用 Nuxt 開發專案的時候,大多數都還是用 Vue2 來進行開發,當@vue/composition-api
出來之後,Nuxt 雖後也推出了 Nuxt Composition API
這個套件,可以讓我們也在 Nuxt 中體會 Composition API 帶來的方便。
先安裝 @nuxtjs/composition-api
npm i @nuxtjs/composition-api
然後再 nuxt.config.js
裡面去設定一下
{
buildModules: [
'@nuxtjs/composition-api/module'
]
}
接下來你就可以好好體驗 Composition API 帶來開發上面的優勢。
在 @nuxtjs/composition-api
上面可以不用自己去包 useStore
跟useRoute
,因為官方已經幫我們包好了
import { useStore, useRoute, useRouter } from '@nuxtjs/composition-api'
export default {
setup() {
const store = useStore()
const route = useRoute()
const router = useRouter()
},
}
詳情可以參考他們官方的文件 :https://composition-api.nuxtjs.org/getting-started/introduction
雖然可能你們的專案暫時沒有辦法升級版本,但是卻可以使用這樣的方式來進行開發,等到之後進行重構,在搬移這些用 Composition API 寫的 component ,就會事半功倍的!
Ps. 購買的時候請登入或註冊該平台的會員,然後再使用下面連結進入網站點擊「立即購課」,這樣才可以讓我獲得更多的課程分潤,還可以幫助我完成更多豐富的內容給各位。
我有開設了一堂專門針對Vue3從零開始教學的課程,如果你覺得不錯的話,可以購買我課程來學習
https://hiskio.com/bundles/9WwPNYRpz?s=tc
那如果對於JS基礎不熟的朋友,我也有開設JS的入門課程,可以參考這個課程
https://hiskio.com/bundles/b9Rovqy7z?s=tc
Mike 的 Youtube 頻道
Mike的medium
MIke 的官方 line 帳號,好友搜尋 @mike_cheng