iT邦幫忙

2021 iThome 鐵人賽

DAY 26
1
Modern Web

[ 重構倒數30天,你的網站不Vue白不Vue ] 系列 第 26

[重構倒數第05天] - 要如何再 Vue2 使用 Composition API

  • 分享至 

  • xImage
  •  

前言

該系列是為了讓看過Vue官方文件或學過Vue但是卻不知道怎麼下手去重構現在有的網站而去規畫的系列文章,在這邊整理了許多我自己使用Vue重構很多網站的經驗分享給讀者們。

Vue3 的 Composition API 一出來就引起來了許多寫 Vue 的工程師熱烈討論,但是如果今天你開發的專案是Vue2的專案,但是又不能說打掉重構,也不能隨便把 Vue2直接升級到 Vue3,但是真的很想體會 Composition API 帶來的好處以及優勢,那該怎麼辦?目前有兩個方法...

https://ithelp.ithome.com.tw/upload/images/20210926/20125854MXquxImrVT.png

  1. Vue 官方說 Vue2.7 會支援 Composition API 的功能,所以即便不升級 Vue 的版本一樣可以使用 Composition API 的這個功能,不過我現在寫這篇文章的時候 Vue 的版本是 2.6.14 ,所以等 Vue2.7 升級之後就可以來玩玩看。
  2. Vue 官方有一個 @vue/composition-api的套件,可以讓 Vue 2.6.14 以下的版本使用 Composition API 的寫法,裝上了這個套件雖然 Vue 的底層還是 object.defineproperty但是可以用 Composition API 來取代 mixin 處理共用邏輯。

@vue/composition-api 是好東西啊!

@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 就好了。

Vuex 使用?

不過這邊要特別注意一下,雖然可以使用 @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 的路徑即可。

如果是 Router呢?

首先我們可以使用一個叫做 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 上面開發呢?

目前使用 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 帶來開發上面的優勢。

如何使用 useStore 還有 useRoute ?

@nuxtjs/composition-api上面可以不用自己去包 useStoreuseRoute,因為官方已經幫我們包好了

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 ,就會事半功倍的!

QRcode

那如果對於Vue3不夠熟的話呢?

Ps. 購買的時候請登入或註冊該平台的會員,然後再使用下面連結進入網站點擊「立即購課」,這樣才可以讓我獲得更多的課程分潤,還可以幫助我完成更多豐富的內容給各位。

我有開設了一堂專門針對Vue3從零開始教學的課程,如果你覺得不錯的話,可以購買我課程來學習
https://hiskio.com/bundles/9WwPNYRpz?s=tc

那如果對於JS基礎不熟的朋友,我也有開設JS的入門課程,可以參考這個課程
https://hiskio.com/bundles/b9Rovqy7z?s=tc

訂閱Mike的頻道享受精彩的教學與分享

Mike 的 Youtube 頻道
Mike的medium
MIke 的官方 line 帳號,好友搜尋 @mike_cheng


上一篇
[重構倒數第06天] - 前端除了要做預覽圖還要把圖片變模糊 !
下一篇
[重構倒數第04天] - 輪播套件難道只可以做圖片輪播嗎
系列文
[ 重構倒數30天,你的網站不Vue白不Vue ] 32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言