S

Vue 2.7 迁移操作记录

·Shinji

Vue2 LTS 马上到期了,手里重要的项目都迁移到 Vue3 了,还剩下的是一个 19 年开始的项目,虽然时间不算太久,但当初是一个刚毕业不久的新人,不知道是从哪找到了一个使用 webpack 构建的项目模板来搭建的,有很多约定和配置与 Vue Cli 不一样。同时 CSS 也并没有使用 TailwindCSS 这类框架,已经封装的 CSS 类也跟目前的主流约定冲突,也很不合理。

最近也有需要动态主题和国际化的需求,反正都是要大动,索性捎带手把 Vue 升到过渡版本 2.7,构建工具替换为 Vite,后续开始使用 Composable API 开发,为整体升级到 Vue3 做好铺垫。

一次性把所有代码都改了不太现实,所以目的是实现 Options API 和 Composable API 共存,一步一步替换。

依赖变更

  • vue^2.7
  • vue-router^3.6
  • @vitejs/plugin-vue2
  • vuex -> Pinia

前三项是依赖是必须的, [email protected] 支持了大部分 Composable API,[email protected] 开始支持 useRouteuseRouter@vitejs/plugin-vue2 是支持 [email protected] 的插件,既然要使用 Composable API,Vuex 也应该换成 Pinia。

Vite

// vite.config.js
import vue from '@vitejs/plugin-vue2';
import Components from 'unplugin-vue-components/vite'; // 推荐使用,自动注册组件,免去频繁手写引入的麻烦

{
  plugins: [
    vue(),
    Components({
      // ...
      version: 2.7, // 必须
      // ...
    }),
  ];
}

Router

import { useRouter, useRoute } from 'vue-router/composables';
// 用法跟vue-router@4一致

template 标签里依然可以使用 $route$router,但建议替换掉,将来升级 Vue3 少点麻烦。

Store

import Vue from 'vue';
import { PiniaVuePlugin, createPinia } from 'pinia';
// 需要写在createPinia之前
Vue.use(PiniaVuePlugin);

渐进替换就需要在 vuex 写入状态时同步写入 pinia。后续在调整具体代码的时候再去实现对应的 action。

Eslint

使用插件 eslint-plugin-vue[email protected] 没有提供 defineOptions 方法,也不支持多个 script 标签,所以如果你需要声明组件 name,则建议使用规则 plugin:vue/vue3-recommended

// .eslintrc.js
extends: ['plugin:vue/vue3-recommended']

之后你就可以这样写,但不知道为什么带 setup 的标签只能是第一个。

<script setup>
//...
</script>
<script>
  export default {
    name: 'YourComponentName'
  }
</script>

CSS

// tainwind.config.js
{
    important: '.tw',
    corePlugins: {
        preflight: false, // 关闭 tailwind reset,项目里已经有了
    },
}

important 是为了声明 tailwindcss 作用域,避免与之前的样式冲突,配置后 tailwind 生成的类都会添加该前缀,比如 .tw :is(.flex)。后续替换代码时在组件根元素上使用 tw 这个 class 就可以,但是根元素上就没办法了,只尽量规避。

Public 目录

如果你需要部署在二级目录,则需要声明 base, Vite 会根据配置自动转换部分标签属性的文件地址,比如 imgsrc,同时组件库的部分 props 也会直接传入静态文件的绝对地址,也需要对其进行声明。JS 代码里声明的文件地址则需要添加前缀 import.meta.env.BASE_URL,比如 ${import.meta.env.BASE_URL}image/1.png

// vite.config.js
{
  plugins: [
    vue({
      template: {
        transformAssetUrls: {
          // for example
          'van-grid-item': ['icon'],
        },
        transformAssetUrlsOptions: {
          base, // recommend
        },
      },
    }),
  ];
}

Volar

VSCode 扩展也可以直接使用 Volar, 如下配置

// jsconfig.js or tsconfig.ts
{
    "vueCompilerOptions": {
        "target": 2.7
     },
}