背景
前段时间使用Vue2完成一个流量回放的前端开发,实现了流量回放的基本功能。开发过程中,发现现主流的插件都在适配Vue3,奈何为了赶进度,只能先用自己熟悉的Vue2先顶上。恰巧最近有些许空余时间,就把项目代码逐步变更Vue3了。过程中,顺便梳理了下遇到的差异,为后面做些许积累与经验参考。
差异处理
element
常见差异:
-
delete
、set
在vue3中不再使用,可以直接将对应的值设置为null
-
router
引入:- Vue2
import Router from 'vue-router'
- Vue3
import {createRouter, createWebHistory} from "vue-router"
- Vue2
-
使用router的history功能,需要添加属性, 指定路径
import {createRouter, createWebHistory} from "vue-router"; const router = createRouter({ history: createWebHistory('/'), routes : []}) export default router
-
从url中获取参数。在 Vue 2 中,
$route
是一个全局属性,但在 Vue 3 中它已被弃用,取而代之的是useRoute()
- vue2
this.recordId = this.$router.history.current.params.id
- vue3
import { useRoute } from 'vue-router'; const route = useRoute(); this.collectionId = route.params.id; console.log(`录制任务ID:${this.collectionId}`);
- vue2
-
处理
eslint
声明后未使用的报错(vue3解决no-unused-vars报错),修改eslintConfig规则{ "eslintConfig": { "root": false, "env": { "node": true }, "extends": [ "plugin:vue/vue3-essential", "eslint:recommended" ], "parserOptions": { "parser": "@babel/eslint-parser" }, "rules": { "no-unused-vars": [ "error", { "varsIgnorePattern": ".*", "args": "none" } ] } }, "browserslist": [ "> 1%", "last 2 versions", "not dead", "not ie 11" ] }
-
:visible.sync
变为v-model
-
自定义按钮弹出框内容:
- Vue2
<el-popconfirm title="是否确定删除?" confirm-button-text="确定" cancel-button-text="取消" @confirm="deleteCollectData(scope.row.id)" > <el-button slot="reference" type="text" size="small">删除 </el-button> </el-popconfirm>
- Vue3
<el-popconfirm title="是否确定删除?" confirm-button-text="确定" cancel-button-text="取消" @confirm="deleteCollectData(scope.row.id)" > <template #reference> <el-button type="primary" size="small">删除 </el-button></template>
- Vue2
-
DatePicker
-
vue2:
<el-date-picker v-model="form.executionTime" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间" :picker-options="pickerOptionsStart" />
-
vue3:
<el-date-picker v-model="form.executionTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择日期时间" />
-
-
el-table
表格数据中的取值方式:- vue2
<el-table :data="tableData" style="width: 100%"> <el-table-column label="Date" width="180"> ----------- <template slot-scope="scope"> ----------- <div style="display: flex; align-items: center"> <el-icon><timer /></el-icon> <span style="margin-left: 10px">{{ scope.row.date }}</span> </div> </template> </el-table-column> </el-table>
- vue3
<el-table :data="tableData" style="width: 100%"> <el-table-column label="Date" width="180"> ----------- <template #default="scope"> ----------- <div style="display: flex; align-items: center"> <el-icon><timer /></el-icon> <span style="margin-left: 10px">{{ scope.row.date }}</span> </div> </template> </el-table-column> </el-table>
- vue2
-
表格数据过滤条件
- vue2
<template slot="header" slot-scope="scope"></template>
- vue3
<template #header></template>
- vue2
-
:value.sync
页面取值为变量-
vue2
<my-component :value.sync="data"></my-component>
-
vue3
<my-component v-model:data="data"></my-component>
-
-
el-link
组件在vue2中,需要使用#
:
<el-link type="primary" :href="'#/replay/jobDetail/'+replay.taskId">{{ replay.taskName }}</el-link>
在vue3中:
<el-link type="primary" :href="'/replay/jobDetail/'+replay.taskId">{{ replay.taskName }}</el-link>
-
slot=
Vue2、Vue3中的差异 footer、extra-
vue2
<div slot="footer" class="dialog-footer"></div>
-
vue3
<template #footer> <div class="dialog-footer"></div> </template>
-
vue2
<el-descriptions class="margin-top" title="任务配置" :column="3"> <template slot="extra"></template> </el-descriptions>
-
vue3
<el-descriptions class="margin-top" title="任务配置" :column="3"> <template #extra></template> </el-descriptions>
-
-
异常处理:
-
Invalid prop: validation failed. Expected one of ["", "default", "small", "large"], got value "mini".
修改vue2中的size='mini'
为size='small'
-
element-plus type.text is about to be deprecated in version 3.0.0, please use link instead.
element-button的type='text'
属性已移除。 -
ResizeObserver loop completed with undelivered notifications
解决改报错,需要修改app.vue
、main.js
两个文件:-
app.vue:
<template> <!-- <img alt="Vue logo" src="./assets/logo.png">--> <!-- <HelloWorld msg="Welcome to Your Vue.js App"/>--> <main> <RouterView /> </main> </template> <script> // app.vue写在script里面 main.js写在app挂在完之后 const debounce = (fn, delay) => { let timer return (...args) => { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn(...args) }, delay) } } const _ResizeObserver = window.ResizeObserver; window.ResizeObserver = class ResizeObserver extends _ResizeObserver{ constructor(callback) { callback = debounce(callback, 200); super(callback); } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
-
main.js:
import {createApp} from 'vue' const app = createApp(App) app.mount('#app') // app.vue写在script里面 main.js写在app挂在完之后 const debounce = (fn, delay) => { let timer return (...args) => { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn(...args) }, delay) } } const _ResizeObserver = window.ResizeObserver; window.ResizeObserver = class ResizeObserver extends _ResizeObserver{ constructor(callback) { callback = debounce(callback, 200); super(callback); } }
-
-
vcrontab
只适用于vue2,在vue3中可以使用vue3-cron-plus
、no-vue3-cron
参考之前分享博客 -
vue-jsonpath-picker
只适用于Vue2,在Vue3中可以使用vue-json-pretty
参考之前分享博客
-