vue路由組件路徑如何用變量形式動(dòng)態(tài)引入
vue路由組件路徑用變量形式動(dòng)態(tài)引入
router.js路由配置文件
import Router from 'vue-router' const createRouter = ()=> new Router({ ? ? mode: 'history', ? ? routes: [] }) const router = createRouter() // 在路由上加一個(gè)全局方法,用于動(dòng)態(tài)添加路由 router.$addRouterPlus = (params)=>{ ? ? router.matcher = new Router({mode: 'history'}).matcher ? ? const rList = [...params] ? ? router.addRoutes(rList) } return router
用變量的形式引入組件
- require:可以正常引入
- import:用這個(gè)引入我這邊是沒(méi)有生效的,網(wǎng)上查資料有說(shuō)是路徑用全變量形式識(shí)別不了,但我加上一段固定路徑也不生效(@/views/${path})
const path= 'views/projectManage/projectInfo.vue'//文件路徑 const menuPathList = [{ ? ? path: '/project', ? ? // component: () => import(`@/${path}`) ? ? component: (resolve)=>require([`@/${path}`], resolve) }] // 更新路由配置 this.$router.$addRouterPlus(this.menuPathList)
vue動(dòng)態(tài)路由導(dǎo)入
靜態(tài)路由的回顧
1.創(chuàng)建router/index.js文件,這里只有一些簡(jiǎn)單的頁(yè)面
import Vue from 'vue' import Router from 'vue-router' import Login from '@/view/login/Login' import Index from '@/layout/Index' import Welcome from '@/layout/welcome/Welcome' Vue.use(Router) export default new Router({ routes: [ { path: '/login', name: 'Login', component: Login }, { path: '/', component: Index, redirect: '/welcome', meta: {requireAuth: true}, children: [ { path: '/welcome', component: Welcome, name: '首頁(yè)', meta: {title: '首頁(yè)', requireAuth: true} } ] } ] })
2.創(chuàng)建router/permission.js文件,配置導(dǎo)航守衛(wèi),可以在每次路由跳轉(zhuǎn)前做一些操作,待會(huì)獲取動(dòng)態(tài)路由操作也在這里配置
import router from '@/router/index' import 'element-ui/lib/theme-chalk/index.css' import '@fortawesome/fontawesome-free/css/all.min.css' import NProgress from 'nprogress' import 'nprogress/nprogress.css' NProgress.configure({ easing: 'ease', // 動(dòng)畫(huà)方式 speed: 500, // 遞增進(jìn)度條的速度 showSpinner: false, // 是否顯示加載ico trickleSpeed: 200, // 自動(dòng)遞增間隔 minimum: 0.3 // 初始化時(shí)的最小百分比 }) // 白名單 const whiteList = ['/login'] // no redirect whitelist // 導(dǎo)航守衛(wèi) router.beforeEach((to, from, next) => { NProgress.start() if (to.meta.requireAuth) { // 判斷該路由是否需要登錄權(quán)限 if (sessionStorage.getItem('loginName') !== null) { // 判斷本地是否存在token next() // 這里是待會(huì)獲取異步路由的地方 } else { // 未登錄,跳轉(zhuǎn)到登陸頁(yè)面 next({ path: '/login' }) } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { if (sessionStorage.getItem('loginName') !== null) { // 判斷本地是否存在token next(`/?redirect=${to.path}`) } else { next(`/login?redirect=${to.path}`) } } } }) router.afterEach(() => { // 在即將進(jìn)入新的頁(yè)面組件前,關(guān)閉掉進(jìn)度條 NProgress.done() })
3.在main.js里引入剛才創(chuàng)建的router下的index.js文件和permission.js文件,如下
import router from '@/router' import './router/permission' new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
4.在App入口中放入路由跳轉(zhuǎn)的視圖區(qū),跳轉(zhuǎn)的路由頁(yè)面都顯示在這里
<div id="app"> <router-view /> </div>
現(xiàn)在靜態(tài)路由就配好了,可以正常的跳轉(zhuǎn)了!
1.首先呢,router/index.js,沒(méi)有什么需要改的,把你需要?jiǎng)討B(tài)獲取的路由信息刪除掉即可,可以留一部分靜態(tài)路由,如登錄頁(yè),首頁(yè)等等,若全刪,routes賦為[]即可。
2.創(chuàng)建一個(gè)文件,我命名為getAsyncRouter.js,用來(lái)處理獲取到的動(dòng)態(tài)路由信息。
// 用于處理動(dòng)態(tài)菜單數(shù)據(jù),將其轉(zhuǎn)為 route 形式 export function fnAddDynamicMenuRoutes (menuList = [], routes = []) { // 用于保存普通路由數(shù)據(jù) let temp = [] // 用于保存存在子路由的路由數(shù)據(jù) let route = [] // 遍歷數(shù)據(jù) for (let i = 0; i < menuList.length; i++) { // 存在子路由,則遞歸遍歷,并返回?cái)?shù)據(jù)作為 children 保存 if (menuList[i].children && menuList[i].children.length > 0) { // 獲取路由的基本格式 route = getRoute(menuList[i]) // 遞歸處理子路由數(shù)據(jù),并返回,將其作為路由的 children 保存 route.children = fnAddDynamicMenuRoutes(menuList[i].children) // 保存存在子路由的路由 routes.push(route) } else { // 保存普通路由 temp.push(getRoute(menuList[i])) } } // 返回路由結(jié)果 return routes.concat(temp) } // 返回路由的基本格式 function getRoute (item) { // 路由基本格式 let route = { // 路由的路徑 path: item.url, // 路由名 name: item.name, // 路由所在組件 // component: (resolve) => require([`@/layout/Index`], resolve), component: (resolve) => require([`@/view${item.curl}`], resolve), meta: { id: item.id, icon: item.icon }, // 路由的子路由 children: [] } // 返回 route return route }
這里是兩個(gè)函數(shù),把獲取到的數(shù)據(jù)處理成路由表數(shù)據(jù),將其變化成 route 的形式。
fnAddDynamicMenuRoutes 用于遞歸菜單數(shù)據(jù)。
getRoute 用于返回某個(gè)數(shù)據(jù)轉(zhuǎn)換的 路由格式。
注釋寫(xiě)的應(yīng)該算是很詳細(xì)了,主要講一下思路:
對(duì)數(shù)據(jù)進(jìn)行遍歷, 定義兩個(gè)數(shù)組(temp,route),temp用于保存沒(méi)有子路由的路由,route 用于保存存在子路由的路由。
如果某個(gè)數(shù)據(jù)存在子路由,則對(duì)子路由進(jìn)行遍歷,并將其返回結(jié)果作為當(dāng)前數(shù)據(jù)的 children。并使用 route 保存路由。
如果某個(gè)數(shù)據(jù)不存在子路由,則直接使用 temp 保存路由。
最后,返回兩者拼接的結(jié)果,即為轉(zhuǎn)換后的數(shù)據(jù)。
route 格式一般如下:
path
:指路由路徑(可以根據(jù)路徑定位路由)。name
:指路由名(可以根據(jù)路由名定位路由)?! ?/li>component
:指路由所在的組件。children
:指的是路由組件中嵌套的子路由。meta
:用于定義路由的一些元信息。
這里有個(gè)大坑?。?! 在配置component的時(shí)候,需要?jiǎng)討B(tài)導(dǎo)入組件,也就是vue異步組件
綜上所述,就是說(shuō),組件的導(dǎo)入可以使用字符串拼接的方式導(dǎo)入,可以使用模板字符串導(dǎo)入(字符串中含有變量),但是使用模板字符串導(dǎo)入時(shí)不能夠只使用變量?。”仨氈付ㄒ粋€(gè)目錄,不能全用變量代替!
3.有了處理動(dòng)態(tài)路由數(shù)據(jù)的函數(shù),那就需要在合適的地方調(diào)用,以發(fā)揮作用。這時(shí)就需要用到beforeEach了,在router/permission.js文件,配置導(dǎo)航守衛(wèi),可以在每次路由跳轉(zhuǎn)前做一些操作,這里就是獲取動(dòng)態(tài)路由了
import router from '@/router/index' import 'element-ui/lib/theme-chalk/index.css' import '@fortawesome/fontawesome-free/css/all.min.css' import NProgress from 'nprogress' import 'nprogress/nprogress.css' import {fnAddDynamicMenuRoutes} from '@/router/getAsyncRouter' import {getRouter} from '@/api/sys/Menu' import store from '@/store' NProgress.configure({ easing: 'ease', // 動(dòng)畫(huà)方式 speed: 500, // 遞增進(jìn)度條的速度 showSpinner: false, // 是否顯示加載ico trickleSpeed: 200, // 自動(dòng)遞增間隔 minimum: 0.3 // 初始化時(shí)的最小百分比 }) // 白名單 const whiteList = ['/login'] // no redirect whitelist // 導(dǎo)航守衛(wèi) router.beforeEach((to, from, next) => { NProgress.start() try { // 判斷是否已經(jīng)獲取過(guò)動(dòng)態(tài)菜單,未獲取,則需要獲取一次 if (store.getters.dynamicRoutes.length === 0) { if (whiteList.indexOf(to.path) !== -1) { next() } else { getRouter().then(res => { if (res.code === 0) { let menuRouter = fnAddDynamicMenuRoutes(res.data[0].children) store.dispatch('app/dynamicRoutes', menuRouter).then(() => { router.addRoutes(store.getters.dynamicRoutes) next({...to, replace: true}) }) } else { console.log('獲取動(dòng)態(tài)路由失敗!') next({path: '/login'}) } }) } } else { // 路由已存在或已緩存路由 if (to.meta.requireAuth) { if (sessionStorage.getItem('loginName') !== null) { // 判斷本地是否存在token next() } else { // 未登錄,跳轉(zhuǎn)到登陸頁(yè)面 next({path: '/login'}) } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { if (sessionStorage.getItem('loginName') !== null) { // 判斷本地是否存在token next(`/?redirect=${to.path}`) } else { next(`/login?redirect=${to.path}`) } } } } } catch (error) { console.log('出錯(cuò)了') next(`/login?redirect=${to.path}`) } }) router.afterEach(() => { // 在即將進(jìn)入新的頁(yè)面組件前,關(guān)閉掉進(jìn)度條 NProgress.done() })
4.接下來(lái)看一看,store的寫(xiě)法
const state = { dynamicRoutes: [] } const mutations = { DYNAMIC_ROUTES (state, routes) { state.dynamicRoutes = routes } } const actions = { dynamicRoutes ({commit}, routes) { commit('DYNAMIC_ROUTES', routes) } }
在刷新頁(yè)面時(shí)遇到一個(gè)問(wèn)題,動(dòng)態(tài)路由表會(huì)隨著vuex的刷新而消失。
處理:這里在app.vue頁(yè)面刷新時(shí)利用sessionStorage存儲(chǔ)一下store,防止刷新丟失vuex。
export default { name: 'App', created () { // 在頁(yè)面加載時(shí)讀取sessionStorage里的狀態(tài)信息 if (sessionStorage.getItem('storeData')) { this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('storeData')))) } // 在頁(yè)面刷新時(shí)將vuex里的信息保存到sessionStorage里 window.addEventListener('beforeunload', () => { sessionStorage.setItem('storeData', JSON.stringify(this.$store.state)) }) // 兼容iphone手機(jī) window.addEventListener('pagehide', () => { sessionStorage.setItem('storeData', JSON.stringify(this.$store.state)) }) } }
//登錄的時(shí)候也調(diào)用一下 getRouter().then(res => { if (res.code === 0) { let menuRouter = fnAddDynamicMenuRoutes(res.data[0].children) store.dispatch('app/dynamicRoutes', menuRouter).then(() => { router.addRoutes(store.getters.dynamicRoutes) }) console.log(store.getters.dynamicRoutes) } else { console.log('獲取動(dòng)態(tài)路由失敗!') router.push('/login') } })
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue循環(huán)中多個(gè)input綁定指定v-model實(shí)例
這篇文章主要介紹了Vue循環(huán)中多個(gè)input綁定指定v-model實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08VUE使用echarts?5.0以上版本渲染器未導(dǎo)入錯(cuò)誤問(wèn)題
這篇文章主要介紹了VUE使用echarts?5.0以上版本渲染器未導(dǎo)入錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06this.$router.push攜帶參數(shù)跳轉(zhuǎn)頁(yè)面的實(shí)現(xiàn)代碼
這篇文章主要介紹了this.$router.push攜帶參數(shù)跳轉(zhuǎn)頁(yè)面,this.$router.push進(jìn)行頁(yè)面跳轉(zhuǎn)時(shí),攜帶參數(shù)有params和query兩種方式,本文結(jié)合實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下2023-04-04vue中關(guān)于$emit和$on的使用及說(shuō)明
這篇文章主要介紹了vue中關(guān)于$emit和$on的使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10微前端qiankun主應(yīng)用與子應(yīng)用之間的跳轉(zhuǎn)示例
這篇文章主要為大家介紹了微前端qiankun主應(yīng)用與子應(yīng)用之間的跳轉(zhuǎn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08