Skip to content

vue2 → vue3

Naoyuki Sano edited this page Feb 4, 2024 · 74 revisions

Guide

Vue 2 to 3
vue-router 3 to 4
vuex 3 to 4
vuex to pinia
@vue/test-utils 1 to 2
Vue CLI 4 to 5
webpack 4 to 5
web-dev-server 3 to 4
Element 2.x to Element Plus
Vuetify upgrade-guide

Not required for vue3 support

polyfill plugin

https://www.npmjs.com/package/node-polyfill-webpack-plugin

Vue 3 - How to add Polyfills to ChainWebpack

npm i node-polyfill-webpack-plugin

migration tools

gogo code
@originjs/vue-codemod
webpack-to-vite

Vue Options to Composition API Converter

miyaoka/vue-composition-converter
fazulk/vue-composition-converter
kalimahapps/vue-options-to-compositio

Bring <script setup> to Vue 2

unplugin-vue2-script-setup

memo

before after files
destroyed unmounted components/DateTime.vue components/config/ConfigTest.vue ConfigBuilder.vue
v-slot:reference #reference
v-slot:option-label #option-label
v-slot:label #label
v-slot:embeddedItem #embeddedItem
v-slot="scope" #default="scope"
@click.native @click
@submit.native.prevent @submit.prevent
:visible.sync v-model:visible
@paste.native @paste
emits: ['input'] emits: ['update:modelValue'],
this.$emit('input', this.$emit('update:modelValue',

package

name vue2 vue3 memo
vue 2.7.14 3.x
vue-router 3.x 4.x Vue 3 Support
vuex 3.x 4.x Vue 3 Support
vue-template-compiler 2.7.14 @vue/compiler-sfc Vue 3 Support
vue-loader 15.x 16.x or 17.x Vue 3 Support
@vue/cli-service 5.0.8 5.0.8 4.5.0 or later
@vue/cli-plugin-babel 5.0.8 5.0.8 4.5.0 or later
@vue/cli-plugin-eslint 5.0.8 5.0.8 4.5.0 or later
@vue/cli-plugin-unit-mocha 5.0.8 5.0.8 4.5.0 or later
@vue/eslint-config-airbnb 6.x 9.x
@vue/test-utils 1.x 2.0.0 or later Vue 3 Support
eslint 8.x 8.x
webpack 5.x 5.x
node-sass 9.x node-sass 9.x or sass
eslint-plugin-vue 9.x 9.x 7.0.0 or later
element-ui 2.x element-plus Vue 3 Support
vue-at 2.5.1 3.0.0-alpha.2 Vue 3 Support
vue-echarts 6.6.1 6.6.1 Vue 3 Support
vuex-persist 3.1.3 3.1.3 Vue 3 Support
emoji-mart-vue-fast 15.0.0 15.0.0 Vue 3 Support
vue-json-pretty 1.x 2.0.0 or later Vue 3 Support
vue-prism-component 1.x 2.0.0 or later Vue 3 Support
@fortawesome/vue-fontawesome 2.x 3.0.0 or later Vue 3 Support
vue-native-websocket 2.0.15 vue-native-websocket-vue3
vue-treeselect 0.4.0 @tanbo800/vue3-treeselect
vue-split-panel 1.x coder-vue3-split-panel
vue-query-builder 0.6.1 × Not Vue3 Support https://github.com/nsano-rururu/vue-query-builder/tree/v0.6.1vue3
vue-js-cron 1.0.5 latest Vue3 Support
- import Router from 'vue-router';
+ import { createRouter, createWebHistory } from 'vue-router';

- export default new Router({
-  mode: 'history',
-  base: process.env.BASE_URL,
+ const router = createRouter({
+   history: createWebHistory(process.env.BASE_URL),

});
+ export default router;
  • vuex
    Change 4.0.0 or later
    store/index.js
import VuexPersistence from 'vuex-persist';
- import Vuex from 'vuex';
+ import { createStore } from 'vuex';
import configs from './configs';
import server from './server';
import metadata from './metadata';
import appconfig from './appconfig';
import elastalert from './elastalert';
import config from './config';
import ui from './ui';

- Vue.use(Vuex);

const vuexLocal = new VuexPersistence({
  storage: window.localStorage,
  reducer: state => ({ ui: state.ui }),
  key: 'praeco-vuex'
});

- export default new Vuex.Store({
+ export default createStore({
  modules: {
    configs,
    server,
    metadata,
    appconfig,
    elastalert,
    config,
    ui
  },
  plugins: [vuexLocal.plugin]
});
npm install -D unplugin-vue-components unplugin-auto-import

vue.config.js

const AutoImport = require('unplugin-auto-import/webpack'); // add
const Components = require('unplugin-vue-components/webpack'); // add
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers'); // add

    plugins: [
      
      // add
      AutoImport.default({
        resolvers: [ElementPlusResolver()],
      }),
      // add
      Components.default({
        resolvers: [ElementPlusResolver()],
      }),
    ],
npm install @element-plus/icons-vue
npm i -D unplugin-icons

https://github.com/antfu/unplugin-icons

vue.config.js

// vue.config.js
module.exports = {
  configureWebpack: {
    plugins: [
      require('unplugin-icons/webpack').default({ /* options */ }),
    ],
  },
}
- icon="el-icon-arrow-right"
+ :icon="ElIconArrowRight"

- icon="el-icon-arrow-down"
+ :icon="ElIconArrowDown"

+ import {
+   ArrowRight as ElIconArrowRight,
+   ArrowDown as ElIconArrowDown,
+ } from '@element-plus/icons-vue';

- icon="el-icon-delete"
+ :icon="ElIconDelete"

+ import { Delete as ElIconDelete } from '@element-plus/icons-vue';
- <i v-if="!testPopoverVisible" class="el-icon-caret-bottom el-icon-right" />
+ <el-icon v-if="!testPopoverVisible" class="el-icon-right"><el-icon-caret-bottom /></el-icon>

- <i v-if="testPopoverVisible" class="el-icon-caret-top el-icon-right" />
+ <el-icon v-if="testPopoverVisible" class="el-icon-right"><el-icon-caret-top /></el-icon>

- <i class="el-icon-loading" />
+ <el-icon><el-icon-loading /></el-icon>

- <el-button icon="el-icon-edit" plain type="primary">
+ <el-button :icon="ElIconEdit" plain type="primary">

- <el-button icon="el-icon-plus" plain type="primary">
+ <el-button :icon="ElIconPlus" plain type="primary">

+ import {
+   Plus as ElIconPlus,  
+   Edit as ElIconEdit,
+   Delete as ElIconDelete,
+ } from '@element-plus/icons-vue';  

- <el-button icon="el-icon-delete" plain type="danger" @click="showDeleteConfirm">
+ <el-button :icon="ElIconDelete" plain type="danger" @click="showDeleteConfirm">

- <i v-if="!silencePopoverVisible" class="el-icon-caret-bottom el-icon-right" />
+ <el-icon v-if="!silencePopoverVisible" class="el-icon-right">
+   <el-icon-caret-bottom />
+ </el-icon>

- <i v-if="silencePopoverVisible" class="el-icon-caret-top el-icon-right" />
+ <el-icon v-if="silencePopoverVisible" class="el-icon-right">
+   <el-icon-caret-top />
+ </el-icon>

- <i v-if="!silencePopoverVisible" class="el-icon-caret-bottom el-icon-right" />
- <i v-if="silencePopoverVisible" class="el-icon-caret-top el-icon-right" />
+ <el-icon v-if="!silencePopoverVisible" class="el-icon-right">
+   <el-icon-caret-bottom />
+ </el-icon>
+ <el-icon v-if="silencePopoverVisible" class="el-icon-right">
+   <el-icon-caret-top />
+ </el-icon>

- icon="el-icon-time" />
+ :icon="ElIconClock" />

- icon="el-icon-edit"
+ :icon="ElIconEdit"

+ import {
+   CaretBottom as ElIconCaretBottom,
+   CaretTop as ElIconCaretTop,  
+   Loading as ElIconLoading,  
+   Clock as ElIconClock,
+ } from '@element-plus/icons-vue';  

+ components: {  
+   ElIconCaretBottom,
+   ElIconCaretTop,
+   ElIconLoading,
+ },

ElNotification

- import { Notification } from 'element-ui';
+ import { ElNotification } from 'element-plus';

- Vue.config.errorHandler = function(err, vm, info) {
+ app.config.errorHandler = function(err, vm, info) {
  logger().error(err);

  console.error(err, vm, info);

- Notification.error({
+ ElNotification({
    message: err.toString(),
    title: 'Internal error',
-    duration: 0
+   duration: 0,
+   type: 'error'
  });
};

el-time-select

-  :picker-options="{
-    start: '00:00',
-    step: '00:15',
-    end: '23:59'
-  }"
+  start="00:00"
+  step="00:15"
+  end="23:59"
- import { Picker, Emoji, EmojiIndex } from 'emoji-mart-vue-fast';
+ import { Picker, Emoji, EmojiIndex } from 'emoji-mart-vue-fast/src';