你好,我是 Kagol。
根据 Vue 官网文档的说明,Vue2 的终止支持时间是 2023 年 12 月 31 日,这意味着从明年开始:
虽然 Vue3 正式版本已经发布快3年了,但据我了解,现在依然还有很多业务在使用 Vue2,迟迟没有升级 Vue3。
为什么要等到 Vue2 彻底停止维护,才考虑升级 Vue3 这个如此重要的问题呢???
本文是一篇 Vue2 升级 Vue3 的指南,主要包含以下部分:
先用 Vue CLI 创建一个 Vue2 项目(也可以使用 Vite 配合 @vitejs/plugin-vue2
或 vite-plugin-vue2
插件)。
// 安装 Vue CLI
npm install -g @vue/cli
// 创建 Vue2 项目
vue create vue2-demo
输出以下信息说明项目创建成功
Successfully created project vue2-demo.
Get started with the following commands:
$ cd vue2-demo
$ yarn serve
创建好之后可以执行以下命令启动项目
yarn serve
输出以下命令说明启动成功
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.1.102:8080/
效果如下
安装 VueRouter
npm i vue-router@3
main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
const router = new VueRouter({
routes: [
{
path: '/',
component: () => import('./components/HomePage.vue')
},
{
path: '/form',
component: () => import('./components/FormPage.vue')
},
{
path: '/list',
component: () => import('./components/ListPage.vue')
}
]
})
Vue.config.productionTip = false
Vue.use(VueRouter)
new Vue({
router,
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<p>
<router-link to="/">Homerouter-link>
<router-link to="/form">Formrouter-link>
<router-link to="/list">Listrouter-link>
p>
<router-view>router-view>
div>
template>
安装 ElementUI
npm i element-ui
在 src/views/FormPage.vue 中使用 ElementUI 组件,从 ElementUI 官网组件 demo 里面拷贝代码即可。
典型表单:https://element.eleme.io/#/zh-CN/component/form#dian-xing-biao-dan
<template>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name">el-input>
el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai">el-option>
<el-option label="区域二" value="beijing">el-option>
el-select>
el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;">el-date-picker>
el-col>
<el-col class="line" :span="2">-el-col>
<el-col :span="11">
<el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;">el-time-picker>
el-col>
el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery">el-switch>
el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type">el-checkbox>
<el-checkbox label="地推活动" name="type">el-checkbox>
<el-checkbox label="线下主题活动" name="type">el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type">el-checkbox>
el-checkbox-group>
el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助">el-radio>
<el-radio label="线下场地免费">el-radio>
el-radio-group>
el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc">el-input>
el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建el-button>
<el-button>取消el-button>
el-form-item>
el-form>
template>
<script>
export default {
data() {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods: {
onSubmit() {
console.log('submit!');
}
}
}
script>
效果如下
表格页面也一样。
src/views/ListPage.vue
<template>
<div>
<div class="filter-bar">
<el-select v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
el-option>
el-select>
<el-date-picker v-model="value1" type="daterange"> el-date-picker>
<el-input
v-model="search"
placeholder="输入关键字搜索"
style="width: 300px"
/>
<el-button>搜索el-button>
div>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"> el-table-column>
<el-table-column prop="name" label="姓名" width="180"> el-table-column>
<el-table-column prop="address" label="地址"> el-table-column>
el-table>
div>
template>
<script>
export default {
data() {
return {
value1: '',
options: [
{
value: '选项1',
label: '王小虎'
},
{
value: '选项2',
label: '张三'
},
{
value: '选项3',
label: '李小萌'
},
{
value: '选项4',
label: '令狐冲'
}
],
value: '',
search: '',
tableData: [
{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
},
{
date: '2016-05-04',
name: '张三',
address: '上海市普陀区金沙江路 1517 弄'
},
{
date: '2016-05-01',
name: '李小萌',
address: '上海市普陀区金沙江路 1519 弄'
},
{
date: '2016-05-03',
name: '令狐冲',
address: '上海市普陀区金沙江路 1516 弄'
}
]
}
}
}
script>
<style lang="less" scoped>
.filter-bar {
display: flex;
& > * {
margin-right: 20px;
}
}
style>
效果如下
首页可以放一张轮播图。
src/views/HomePage.vue
<template>
<el-carousel>
<el-carousel-item v-for="item in 4" :key="item">
<img :src="`https://picsum.photos/1350/900?random=${item}`" style="width: 100%;">
el-carousel-item>
el-carousel>
template>
<style>
.el-carousel__item h3 {
color: #475669;
font-size: 14px;
opacity: 0.75;
line-height: 150px;
margin: 0;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
style>
效果如下
参考:
OpenTiny Vue 的组件都是支持按需引入的,一开始我们步子不要迈得太大,先尝试替换一个 Button 组件。
安装 @opentiny/vue@2
npm i @opentiny/vue@2
表单页面里面有两个按钮,我们尝试将其替换成 OpenTiny Vue 的 Button 组件。
替换的步骤很简单,不需要修改现有的代码,只需要增加4行代码即可。
src/views/FormPage.vue
...
立即创建
取消
效果如下
接下来我们步子逐渐迈大一点,将整个 FormPage 页面的 ElementUI 组件全部替换成 OpenTiny Vue 的组件。
FormPage 页面一共有以下组件:
替换的方式和前面替换 Button 组件一模一样,只需要多加一些组件。
...
立即创建
取消
效果如下
最后一步就是使用 OpenTiny Vue 替换整个应用的 ElementUI。
我们可以用前面的方法进行替换,但考虑到整个应用的页面众多,我们采取另一种方式。
我们已经全局注册了 ElementUI 组件库,接下来我们全局注册 OpenTiny Vue 组件库。
import Vue from 'vue'
- import ElementUI from 'element-ui'
- import 'element-ui/lib/theme-chalk/index.css'
+ import TinyVue from '@opentiny/vue'
import App from './App.vue'
import VueRouter from 'vue-router'
- Vue.use(ElementUI)
+ Vue.use(TinyVue)
const router = new VueRouter({
routes: [
...
]
})
Vue.config.productionTip = false
Vue.use(VueRouter)
new Vue({
router,
render: (h) => h(App)
}).$mount('#app')
然后全局替换 el-
为 tiny-
,一步到位!
效果如下
首页轮播
表单
表格
是不是非常丝滑,更丝滑的还在后面!
接下来我们将借助一款神器:gogocode,实现 Vue2 项目平滑升级 Vue3。
安装 gogocode:
npm install gogocode-cli -g
转换源码:
gogocode -s ./src/ -t gogocode-plugin-vue -o ./src/
升级依赖:
gogocode -s package.json -t gogocode-plugin-vue -o package.json
升级 TinyVue 组件库到 3.0 版本
npm i @opentiny/vue@3
组件代码无需做任何修改,完成 Vue2 项目平滑升级到 Vue3
执行 npm run dev
命令启动项目,除了 Vue 版本号变化之后,其他任何效果都没有变化。
首页轮播
表单
表格
问题一:error ‘v-model’ directives require no argument vue/no-v-model-argument
解决方法:修改 FormPage.vue 中的 v-model:value 为 v-model 即可
问题二:Failed to resolve component: router-link
解决方案:修改 main.js 中 use(router) 代码顺序即可
window.$vueApp = Vue.createApp(App)
window.$vueApp.mount('#app')
import * as Vue from 'vue'
import TinyVue from '@opentiny/vue'
import App from './App.vue'
import * as VueRouter from 'vue-router'
- window.$vueApp.use(TinyVue)
const router = VueRouter.createRouter({
history: VueRouter.createWebHashHistory(),
routes: [
...
],
})
window.$vueApp = Vue.createApp(App)
+ window.$vueApp.use(TinyVue)
+ window.$vueApp.use(router) // 这一行代码需要放到 mount 之前
window.$vueApp.mount('#app')
window.$vueApp.config.globalProperties.routerAppend = (path, pathToAppend) => {
return path + (path.endsWith('/') ? '' : '/') + pathToAppend
}
- window.$vueApp.use(router)
如果你在升级 Vue3 的过程中遇到任何问题,欢迎在评论区进行讨论,也欢迎添加 OpenTiny 小助手 opentiny-official
与我们交流!
本文涉及到的源码链接:
Element 升级 OpenTiny 的 demo 项目在 packages/element-to-opentiny 子包里。
vue2
分支vue3
分支OpenTiny 是一套华为云出品的企业级组件库解决方案,适配 PC 端 / 移动端等多端,涵盖 Vue2 / Vue3 / Angular 多技术栈,拥有主题配置系统 / 中后台模板 / CLI 命令行等效率提升工具,可帮助开发者高效开发 Web 应用。
核心亮点:
跨端跨框架
:使用 Renderless 无渲染组件设计架构,实现了一套代码同时支持 Vue2 / Vue3,PC / Mobile 端,并支持函数级别的逻辑定制和全模板替换,灵活性好、二次开发能力强。组件丰富
:PC 端有80+组件,移动端有30+组件,包含高频组件 Table、Tree、Select 等,内置虚拟滚动,保证大数据场景下的流畅体验,除了业界常见组件之外,我们还提供了一些独有的特色组件,如:Split 面板分割器、IpAddress IP地址输入框、Calendar 日历、Crop 图片裁切等配置式组件
:组件支持模板式和配置式两种使用方式,适合低代码平台,目前团队已经将 OpenTiny 集成到内部的低代码平台,针对低码平台做了大量优化周边生态齐全
:提供了基于 Angular + TypeScript 的 TinyNG 组件库,提供包含 10+ 实用功能、20+ 典型页面的 TinyPro 中后台模板,提供覆盖前端开发全流程的 TinyCLI 工程化工具,提供强大的在线主题配置平台 TinyTheme欢迎加入 OpenTiny 开源社区。
添加微信小助手:opentiny-official,一起参与共建!
OpenTiny 官网:https://opentiny.design/
Vue组件库:https://opentiny.design/tiny-vue
Angular组件库:https://opentiny.design/tiny-ng
OpenTiny 代码仓库:https://github.com/opentiny/ (欢迎 Star ⭐)
往期文章推荐