vue2+vite升级到vue3

159 阅读1分钟

1、更换依赖包

@vitejs/plugin-vue2更换成@vitejs/plugin-vue
@vitejs/plugin-vue2-jsx更换成@vitejs/plugin-vue-jsx
element-ui更换成element-plus和@element-plus/icons-vue
vue2.7.14更换成vue3.4.33
vue2-scale-box更换成vue2-scale-box
vuex更换成pinia
vue-router3.4.9更换成4.4.0

2、修改router

vue2:
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  mode: 'history', // 去掉url中的#
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes,
})


<transition name="fade-transform" mode="out-in">
  <keep-alive :include="cachedViews">
    <router-view :key="key" />
  </keep-alive>
</transition>

vue3:
import { createRouter, createWebHashHistory } from "vue-router";

export default createRouter({
  history: createWebHashHistory(),
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes,
});

<router-view v-slot="{ Component }">
  <transition name="fade-transform" mode="out-in">
    <keep-alive :include="cachedViews">
      <component :is="Component" />
    </keep-alive>
  </transition>
</router-view>

注:
404路由配置需要修改
    { path: '*', redirect: '/404', hidden: true }
    修改成:
    { path: '/:catchAll(.*)', redirect: '/404', hidden: true }

动态路由加载:
    () => import(`@/views/${view}`)
    修改成:
    const modules = import.meta.glob('@/views/**/*.vue')
    modules['/src/views/' + view + '.vue']

3、修改store

vue2:
    import { createStore } from 'vuex'

    // 创建一个新的 store 实例
    const store = createStore({
      state () {
        return {
          count: 0
        }
      },
      getters: {
          double (state) {
            return state.count * 2
          }
        },
      mutations: {
        INcrement (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          context.commit('INcrement')
        }
      }
    })
    
vue3:
    import { defineStore } from 'pinia'
    export const useCounterStore = defineStore('counter', {
      state: () => ({ count: 0 }),
      getters: {
        double: (state) => state.count * 2,
      },
      actions: {
        increment() {
          this.count++
        },
      },
    })
    

4、修改main.js

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import store from './store'
import router from './router'
import Element from 'element-plus'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(createPinia())
app.use(store);
app.use(router)
app.use(Element, {
  size: Cookies.get('size') || 'medium', // set element-ui default size
})
//添加element的图标组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}


// 全局方法挂载(vue2写法:Vue.prototype.XX = XX)
app.config.globalProperties.XX = XX

app.mount('#app')

5、jsx文件修改

import {h} from vue;

6、sync修饰符修改

vue2:
 <right-toolbar
    :showSearch.sync="showSearch"
    @queryTable="getList"
  ></right-toolbar>
  
  vue3:
  <right-toolbar
    v-model:showSearch="showSearch"
    @queryTable="getList"
  ></right-toolbar>

7、$listener会报错

vue2:
v-bind="$attrs" v-on="$listener"

vue3:
v-bind="$attrs"

8、element-plus与elementui写法区别(具体见官方文档)

element-plus官网:Button 按钮 | Element Plus (element-plus.org)

vue2:
    图标
    <i class="el-icon-close"></i>
    <el-button type="primary" icon="el-icon-search">搜索</el-button>
    
    上传文件
    <el-upload><div slot="tip">请上传</div></el-upload>
    
    dropdown下拉菜单
    <el-dropdown>
        <span>
          Dropdown List
          <i class="el-icon-caret-bottom" />
        </span>
        <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>Action 1</el-dropdown-item>
        </el-dropdown-menu>
    </el-dropdown>
    
    弹窗
    <el-dialog title="弹窗标题" :visible.sync="open">
        我是弹窗
        <div slot="footer">
        </div>
    </el-dialog>
    
    menu菜单
    <el-menu
      :default-active="activeIndex"
      mode="horizontal"
    >
      <el-menu-item index="1">处理中心</el-menu-item>
      <el-submenu index="2">
        <template slot="title">我的工作台</template>
        <el-menu-item index="2-1">选项1</el-menu-item>
      </el-submenu>
    </el-menu>
    
    获取滚动条dom
    <el-scrollbar ref="scrollContainer"></el-scrollbar>
    console.log(this.$refs.scrollContainer.$refs.wrap)
    
    表格:
    <el-table>
      <el-table-column label="名称" align="center" prop="name">
        <template slot-scope="scope">{{scope.row.name}}</template></el-table-column
      ></el-table
    >
    
    单选
    <el-radio-group v-model="radio2"> <el-radio label="1">Option 1</el-radio> <el-radio label="2">Option 2</el-radio> </el-radio-group>

    
vue3:
    图标
    <el-icon><Close/></el-icon>
    <el-button type="primary" icon="Search">搜索</el-button>
    
    下拉框
    <el-select>在form表单时inline的模式下需要手动设置宽度
       
    上传文件
    <el-upload><template #tip>请上传</template></el-upload>
    
    dropdown下拉菜单
    <el-dropdown>
        <span>
          Dropdown List
          <el-icon><CaretBottom /></el-icon>
        </span>
        <template #dropdown>
            <el-dropdown-menu>
                <el-dropdown-item>Action 1</el-dropdown-item>
            </el-dropdown-menu>
        </template>
    </el-dropdown>
    
    弹窗
    <el-dialog title="弹窗标题" v-model="open">
        我是弹窗
        <template #footer>
            <div>
            </div>
        </template>
    </el-dialog>
    
    menu菜单
    <el-menu
      :default-active="activeIndex"
      mode="horizontal"
    >
      <el-menu-item index="1">处理中心</el-menu-item>
      <el-sub-menu index="2">
        <template slot="title">我的工作台</template>
        <el-menu-item index="2-1">选项1</el-menu-item>
      </el-sub-menu>
    </el-menu>
    
    获取滚动条dom
    <el-scrollbar ref="scrollContainer"></el-scrollbar>
    console.log(this.$refs.scrollContainer.$refs.wrapRef)
    
    表格
    <el-table>
      <el-table-column label="名称" align="center" prop="name">
        <template #default="scope">{{scope.row.name}}</template></el-table-column
      ></el-table
    >
    
    单选
    <el-radio-group v-model="radio2"> <el-radio value="1">Option 1</el-radio> <el-radio value="2">Option 2</el-radio> </el-radio-group>

9、element中文化

在app.vue中修改:
 <el-config-provider :locale="locale">
    <router-view />
</el-config-provider>

<script>
import { ElConfigProvider } from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
export default {
  name: 'App',
  components: {
    [ElConfigProvider.name]: ElConfigProvider,
  },
}
</script>

10、动态添加属性

vue2:
this.$set(this.form, 'userName', 'aaa');

vue3:
Reflect.set(this.form, 'userName', 'aaa');