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

前言

该系列是为了让看过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


<<:  [Lesson11] SQLite

>>:  Day26 ( 高级 ) 放烟火 2 ( 爆炸效果 )

Day 04:.vue 档三层柜

继上篇观察整个专案资料夹结构之後,接着来观察子层 components 资料夹里的 HelloWor...

Day43 ( 电子元件 ) 触碰开灯 ( 引脚按下 )

触碰开灯 ( 引脚按下 ) 教学原文参考:触碰开灯 ( 引脚按下 ) 这篇文章会介绍如何使用「当引脚...

[Day12] TS:什麽!型别还有递回(recursion)的概念?用组合技实作 SnakeToCamelCase

这是我们今天要聊的内容,老样的,如果你已经可以轻松看懂,欢迎直接左转去看我同事 Andy 精彩的文...

[Day2] 电脑视觉下的人脸

万般皆是脸 注:在接下来的内容里,我会着重在"图片"下的人脸辨识 (包含摄影机...

Day21

今天继续看指标与阵列陷入深深地不知该如何写心得中,指标*ptr是专门用来指向物件记忆体位置的类型。在...