vue3+vite動(dòng)態(tài)加載路由,本地路由和線上路由匹配方式
使用場景
本地全路由動(dòng)態(tài)匹配線上路由
目的
本地路由方便開發(fā)配置,匹配線上路由,進(jìn)行頁面路由控制
內(nèi)容
// router/constRoutes.js
// ---------------------------------------
// constRoutes 固定需要加載的路由,
// notFound 動(dòng)態(tài)路由加載完成后再添加,否則刷新頁面,此時(shí)還沒有路由,會(huì)直接定向到notFound頁面
// ---------------------------------------
export const constRoutes = [
? {
? ? path: '/',
? ? redirect: '/home'
? },
? {
? ? path: '/home',
? ? name: 'home',
? ? component: () => import('@/views/home/index.vue')
? },
? {
? ? path: '/login',
? ? name: 'login',
? ? component: () => import('@/views/login/index.vue')
? }
]
export const notFound = {
? path: '/:pathMatch(.*)*',
? name: 'notFound',
? component: () => import('@/views/not-found/not-found.vue')
}// router/asyncRoutes.js
// ---------------------------------------
// 注意:children下的path不需要加'/'
// meta下可以加各種本地你想要的參數(shù)
// ---------------------------------------
const Layout = () => import('@/layout/index.vue')
export const asyncRoutes = [
? {
? ? path: '/monitoringCenter',
? ? name: 'MonitoringCenter',
? ? component: Layout,
? ? meta: { title: '監(jiān)控中心' },
? ? children: [
? ? ? {
? ? ? ? path: 'carMonitoring',
? ? ? ? name: 'CarMonitoring',
? ? ? ? meta: { title: '車輛監(jiān)控' },
? ? ? ? children: [
? ? ? ? ? {
? ? ? ? ? ? path: 'positioning',
? ? ? ? ? ? name: 'Positioning',
? ? ? ? ? ? component: () => import('@/views/monitoringCenter/positioning/index.vue'),
? ? ? ? ? ? meta: { title: '實(shí)時(shí)定位' }
? ? ? ? ? }
? ? ? ? ]
? ? ? },
? ? ? {
? ? ? ? path: 'monitorSetting',
? ? ? ? name: 'MonitorSetting',
? ? ? ? meta: { title: '監(jiān)控設(shè)置' },
? ? ? ? children: [
? ? ? ? ? {
? ? ? ? ? ? path: 'ruleManagement',
? ? ? ? ? ? name: 'RuleManagement',
? ? ? ? ? ? component: () => import('@/views/monitoringCenter/ruleManagement/index.vue'),
? ? ? ? ? ? meta: { title: '報(bào)警規(guī)則' }
? ? ? ? ? }
? ? ? ? ]
? ? ? }
? ? ]
? },// router/index.js
// ---------------------------------------
// 先加載constRoutes 固定路由
// ---------------------------------------
import { createRouter, createWebHistory } from 'vue-router'
import { constRoutes } from '@/router/constRoutes'
const router = createRouter({
? history: createWebHistory(import.meta.env.BASE_URL),
? routes: constRoutes
})
export default router// utils/map-menus.js
// ---------------------------------------
//導(dǎo)出方法,menuList是線上路由,Routes第一次默認(rèn)是本地路由
// ---------------------------------------
import { asyncRoutes } from '@/router/asyncRoutes'
// 添加redirect重定向
let redirect = ''
// 匹配路由,添加對應(yīng)線上傳回來的參數(shù)
export function mapMenusToRoutes(menuList, Routes = asyncRoutes) {
? const routes = []
? for (let item of Routes) {
? ? const m = menuList.find((menu) => item.name == menu.name)
? ? if (m) {
? ? // 線上按鈕權(quán)限放在attr中
? ? ? m.attr && m.attr.length && (item.attr = m.attr)
? ? ? item.id = m.id
? ? ? // ‘?.'判斷是否有children且大于零
? ? ? if (item.children?.length) {
? ? ? ?? ?// 添加重定向
? ? ? ? if (item.path.includes('/')) {
? ? ? ? ? redirect = item.path
? ? ? ? ? item.redirect = `${redirect}/${item.children[0].path}`
? ? ? ? } else {
? ? ? ? ? item.redirect = `${redirect}/${item.path}/${item.children[0].path}`
? ? ? ? }
? ? ? ? // 如果有children 則回調(diào)并賦值
? ? ? ? item.children = mapMenusToRoutes(m.children, item.children)
? ? ? }
? ? ? routes.push(item)
? ? }
? }
? return routes
}&&&&后面是具體調(diào)用方式,因人而異,可自行選擇
// stores/login.js
import { defineStore } from 'pinia'
import router from '@/router'
import { notFound } from '@/router/constRoutes'
import localCache from '@/utils/cache'
import { mapMenusToRoutes } from '@/utils/map-menus'
import { login, getInfo } from '@/api/user/login'
export const useLoginStore = defineStore({
? id: 'useLoginStore',
? state: () => ({
? ? token: '',
? ? menuList: [],
? ? routeMenus: []
? }),
? getters: {
? ? routeMenusGet() {
? ? ? return this.routeMenus
? ? }
? },
? actions: {
? ? async LoginAction(loginForm) {
? ? ? // 1.實(shí)現(xiàn)登錄邏輯
? ? ? const { data: loginData } = await login(loginForm)
? ? ? this.token = loginData.token
? ? ? // 保存至localStorage,方法隨意
? ? ? localCache.setCache('token', this.token)
? ? ? // 2.跳轉(zhuǎn)至首頁
? ? ? router.push('/home')
? ? },
? ? // router.beforeEach獲取菜單樹
? ? async getInfoAction() {
? ? ? const infoData = await getInfo({ token: this.token })
? ? ? this.menuList = infoData.data.menuList
? ? ? this.addRouteMenus()
? ? },
? ? // 動(dòng)態(tài)加載路由
? ? addRouteMenus() {
? ? ? this.routeMenus = mapMenusToRoutes(this.menuList)
? ? ? // vue3中只有addRoute
? ? ? for (let item of this.routeMenus) {
? ? ? ? router.addRoute(item)
? ? ? }
? ? ? // 最后添加,否則刷新請求線上路由時(shí),還沒有加載完,會(huì)直接定向到notFound
? ? ? router.addRoute(notFound)
? ? }
? }
})// src/permission.js
// main.js中引入次文件 import '@/permission'
import router from './router'
import localCache from '@/utils/cache'
import { useLoginStore } from '@/stores/user/login'
router.beforeEach(async (to, from, next) => {
? document.title = `${to.meta.title}`
? if (to.path === '/login') {
? ?? ?// 清空localStorage
? ? localCache.clearCache()
? ? next()
? } else {
? ? const token = localCache.getCache('token')
? ? if (!token) {
? ? ? next(`/login`)
? ? } else {
? ? ? const loginStore = useLoginStore()
? ? ? if (loginStore.routeMenus.length) {
? ? ? ? next()
? ? ? } else {
? ? ? // 如果沒有路由,調(diào)用動(dòng)態(tài)加載路由
? ? ? ? try {
? ? ? ? ? await loginStore.getInfoAction()
? ? ? ? ? next({ ...to, replace: true })
? ? ? ? } catch (error) {
? ? ? ? ? next(`/login`)
? ? ? ? }
? ? ? }
? ? }
? }
})總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- vite+vue3+tsx項(xiàng)目打包后動(dòng)態(tài)路由無法加載頁面的問題及解決
- vue3 vite pinia配置動(dòng)態(tài)路由、解決刷新頁面路由消失的問題
- Vue3+vite路由配置優(yōu)化(自動(dòng)化導(dǎo)入)
- vite?vue3下配置history模式路由的步驟記錄
- Vue3使用路由及配置vite.alias簡化導(dǎo)入寫法的過程詳解
- Vue3+Vite實(shí)現(xiàn)動(dòng)態(tài)路由的詳細(xì)實(shí)例代碼
- vue3?vite異步組件及路由懶加載實(shí)戰(zhàn)示例
- vite vue3 路由配置@找不到文件的問題及解決
相關(guān)文章
vue實(shí)現(xiàn)el-menu和el-tab聯(lián)動(dòng)的示例代碼
本文主要介紹了vue實(shí)現(xiàn)el-menu和el-tab聯(lián)動(dòng)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
Vue通過路由實(shí)現(xiàn)頁面間參數(shù)的傳遞
這篇文章主要介紹了Vue通過路由實(shí)現(xiàn)頁面間參數(shù)的傳遞,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
vue實(shí)現(xiàn)進(jìn)入某個(gè)頁面后替換地址欄路徑的操作方法
vue頁面在實(shí)際開發(fā)中,經(jīng)常會(huì)遇到改變url參數(shù),重新加載頁面數(shù)據(jù)的需求,但是只改變頁面url并不會(huì)觸發(fā)組件的生命周期,這就需要用其他方法來實(shí)現(xiàn)了,本文重點(diǎn)介紹vue實(shí)現(xiàn)進(jìn)入某個(gè)頁面后替換地址欄路徑的操作方法,感興趣的朋友跟隨小編一起看看吧2024-04-04
element的el-table中記錄滾動(dòng)條位置的示例代碼
這篇文章主要介紹了element的el-table中記錄滾動(dòng)條位置的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
實(shí)現(xiàn)一個(gè)Vue自定義指令懶加載的方法示例
這篇文章主要介紹了實(shí)現(xiàn)一個(gè)Vue自定義指令懶加載的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Cookbook組件形式:優(yōu)化 Vue 組件的運(yùn)行時(shí)性能
本文仿照Vue Cookbook 組織形式,對優(yōu)化 Vue 組件的運(yùn)行時(shí)性能進(jìn)行闡述。通過基本的示例代碼給大家講解,需要的朋友參考下2018-11-11
vue中使用axios post上傳頭像/圖片并實(shí)時(shí)顯示到頁面的方法
今天小編就為大家分享一篇vue中使用axios post上傳頭像/圖片并實(shí)時(shí)顯示到頁面的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
Ant?Design?Vue?走馬燈實(shí)現(xiàn)單頁多張圖片輪播效果
這篇文章主要介紹了Ant?Design?Vue?走馬燈實(shí)現(xiàn)單頁多張圖片輪播,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07

