admin管理员组文章数量:1633739
静态路由的回顾
- 1.创建router/index.js文件,这里只有一些简单的页面
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: '首页',
meta: {title: '首页', requireAuth: true}
}
]
}
]
})
2.创建router/permission.js文件,配置导航守卫,可以在每次路由跳转前做一些操作,待会获取动态路由操作也在这里配置
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', // 动画方式
speed: 500, // 递增进度条的速度
showSpinner: false, // 是否显示加载ico
trickleSpeed: 200, // 自动递增间隔
minimum: 0.3 // 初始化时的最小百分比
})
// 白名单
const whiteList = ['/login'] // no redirect whitelist
// 导航守卫
router.beforeEach((to, from, next) => {
NProgress.start()
if (to.meta.requireAuth) {
// 判断该路由是否需要登录权限
if (sessionStorage.getItem('loginName') !== null) {
// 判断本地是否存在token
next()
// 这里是待会获取异步路由的地方
} else {
// 未登录,跳转到登陆页面
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(() => {
// 在即将进入新的页面组件前,关闭掉进度条
NProgress.done()
})
3.在main.js里引入刚才创建的router下的index.js文件和permission.js文件,如下
import router from '@/router'
import './router/permission'
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
4.在App入口中放入路由跳转的视图区,跳转的路由页面都显示在这里
<div id="app">
<router-view />
</div>
现在静态路由就配好了,可以正常的跳转了!
1.首先呢,router/index.js,没有什么需要改的,把你需要动态获取的路由信息删除掉即可,可以留一部分静态路由,如登录页,首页等等,若全删,routes赋为[]即可。2.创建一个文件,我命名为getAsyncRouter.js,用来处理获取到的动态路由信息。
// 用于处理动态菜单数据,将其转为 route 形式
export function fnAddDynamicMenuRoutes (menuList = [], routes = []) {
// 用于保存普通路由数据
let temp = []
// 用于保存存在子路由的路由数据
let route = []
// 遍历数据
for (let i = 0; i < menuList.length; i++) {
// 存在子路由,则递归遍历,并返回数据作为 children 保存
if (menuList[i].children && menuList[i].children.length > 0) {
// 获取路由的基本格式
route = getRoute(menuList[i])
// 递归处理子路由数据,并返回,将其作为路由的 children 保存
route.children = fnAddDynamicMenuRoutes(menuList[i].children)
// 保存存在子路由的路由
routes.push(route)
} else {
// 保存普通路由
temp.push(getRoute(menuList[i]))
}
}
// 返回路由结果
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
}
这里是两个函数,把获取到的数据处理成路由表数据,将其变化成 route 的形式。
fnAddDynamicMenuRoutes 用于递归菜单数据。 getRoute 用于返回某个数据转换的 路由格式。
注释写的应该算是很详细了,主要讲一下思路: 对数据进行遍历, 定义两个数组(temp,route),temp
用于保存没有子路由的路由,route 用于保存存在子路由的路由。 如果某个数据存在
子路由,则对子路由进行遍历,并将其返回结果作为当前数据的 children。并使用 route 保存路由。
如果某个数据不存在子路由,则直接使用 temp 保存路由。 最后,返回两者拼接的结果,即为转换后的数据。 route 格式一般如下:
path:指路由路径(可以根据路径定位路由)。 name:指路由名(可以根据路由名定位路由)。
component:指路由所在的组件。 children:指的是路由组件中嵌套的子路由。 meta:用于定义路由的一些元信息。这里有个大坑!!! 在配置component的时候,需要动态导入组件,也就是vue异步组件
综上所述,就是说,组件的导入可以使用字符串拼接的方式导入,可以使用模板字符串导入(字符串中含有变量),但是使用模板字符串导入时不能够只使用变量!!必须指定一个目录,不能全用变量代替!
3.有了处理动态路由数据的函数,那就需要在合适的地方调用,以发挥作用。这时就需要用到beforeEach了,在router/permission.js文件,配置导航守卫,可以在每次路由跳转前做一些操作,这里就是获取动态路由了
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', // 动画方式
speed: 500, // 递增进度条的速度
showSpinner: false, // 是否显示加载ico
trickleSpeed: 200, // 自动递增间隔
minimum: 0.3 // 初始化时的最小百分比
})
// 白名单
const whiteList = ['/login'] // no redirect whitelist
// 导航守卫
router.beforeEach((to, from, next) => {
NProgress.start()
try {
// 判断是否已经获取过动态菜单,未获取,则需要获取一次
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('获取动态路由失败!')
next({path: '/login'})
}
})
}
} else {
// 路由已存在或已缓存路由
if (to.meta.requireAuth) {
if (sessionStorage.getItem('loginName') !== null) {
// 判断本地是否存在token
next()
} else {
// 未登录,跳转到登陆页面
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('出错了')
next(`/login?redirect=${to.path}`)
}
})
router.afterEach(() => {
// 在即将进入新的页面组件前,关闭掉进度条
NProgress.done()
})
4接下来看一看,store的写法
const state = {
dynamicRoutes: []
}
const mutations = {
DYNAMIC_ROUTES (state, routes) {
state.dynamicRoutes = routes
}
}
const actions = {
dynamicRoutes ({commit}, routes) {
commit('DYNAMIC_ROUTES', routes)
}
}
在刷新页面时遇到一个问题,动态路由表会随着vuex的刷新而消失。
处理:这里在app.vue页面刷新时利用sessionStorage存储一下store,防止刷新丢失vuex。
export default {
name: 'App',
created () {
// 在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem('storeData')) {
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('storeData'))))
}
// 在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('storeData', JSON.stringify(this.$store.state))
})
// 兼容iphone手机
window.addEventListener('pagehide', () => {
sessionStorage.setItem('storeData', JSON.stringify(this.$store.state))
})
}
}
//登录的时候也调用一下
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('获取动态路由失败!')
router.push('/login')
}
})
版权声明:本文标题:vue动态路由导入 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1729175390a1188648.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论