后端技术:PHP
前端:Vue2 、vue-admin-element
1.静态路由
/* @/router/index.js */
import Vue from 'vue'
import Router from 'vue-router'
import newPcAsyncRoutes from './modules/asyncRoutes'
import newMobileAsyncRoutes from './modules/mobileRoutes'
import Layout from '@/layout'
import { _isMobile } from '@/utils/isMobile'
Vue.use(Router)
export const pcConstantRoutes = [
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path(.*)',
component: () => import('@/views/redirect/index')
}
]
},
{
path: '/login',
component: () =>
_isMobile()
? import('@/views/mobilePages/views/login/index')
: import('@/views/login/index'),
hidden: true
}
// 404页面必须放最后
// { path: '*', redirect: '/404', hidden: true }
]
export const constantRoutes = pcConstantRoutes
/* 异步挂载路由 */
/* //动态需要根据权限加载的路由表 1.前端自定义router放置 */
const NewPcAsyncRoutes = newPcAsyncRoutes
const NewMobileAsyncRoutes = newMobileAsyncRoutes
export const newAsyncRoutes = _isMobile()
? NewMobileAsyncRoutes
: NewPcAsyncRoutes
const createRouter = () =>
new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: [...constantRoutes]
})
const router = createRouter()
// 重置路由
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher
}
export default router
2.路由处理方法
/* @/utils/MyRouter.js */
import Layout from '@/layout'
/* 生成配置的路由表结构 */
function MenuChange(obj) {
function treeToArr(obj, pid = 0, res = []) {
for (const key in obj) {
if (obj[key].parent) {
res.push({
pid: pid,
id: obj[key].parent.id,
title: obj[key].parent.title,
info: obj[key].parent.info,
has_child: obj[key].parent.has_child,
promptstr: obj[key].parent.promptstr
})
if (obj[key].parent.has_child) {
treeToArr(obj[key].child, obj[key].parent.id, res)
}
}
}
return res
}
const arr = treeToArr(obj)
// console.log(arr, 'treeToArr')
function arrToTree(arr, pid = 0) {
const res = []
arr.forEach(item => {
if (item.pid === 0) {
// console.log(item, 'item')
item['path'] = item.title === 'homepage' ? '/' : '/' + item.title
item['redirect'] =
item.title === 'homepage' ? '/homepage' : '/' + item.title
item['alwaysShow'] = item.title !== 'homepage'
item['component'] = Layout
item['children'] = [
{
path: item.title,
name: item.title,
component: resolve => require([`@/views/${item.title}`], resolve),
meta: {
title: item.info,
icon: item.title,
prompt: item.promptstr,
keepAlive: item.title === 'allresult' || item.title === 'setbompc'
// 控制外层 allresult缓存
}
}
]
if (item.has_child !== 0) {
// console.log(item, '---item')
item['meta'] = {
title: item.info,
icon: item.title,
keepAlive: item.title === 'allresult' || item.title === 'setbompc'
}
}
}
if (item.pid !== 0) {
if (item.has_child !== 0) {
// console.log(item, '---item2')
item['alwaysShow'] = true
}
item['path'] = item.title
item['component'] = {
render(c) {
return c('router-view')
}
}
item['name'] = item.title
!item.has_child &&
(item.component = resolve =>
require([`@/views/${item.title}`], resolve))
item['meta'] = {
title: item.info,
icon: item.title,
keepAlive: item.title === 'allresult' || item.title === 'setbompc'
}
!item.has_child && (item.meta.prompt = item.promptstr)
}
if (item.pid === pid) {
const children = arrToTree(
arr.filter(v => v.pid !== pid),
item.id
)
if (children.length) {
res.push({ ...item, children })
} else {
res.push({ ...item })
}
}
})
return res
}
const tree = arrToTree(arr)
// console.log(tree, 'tree')
return tree
}
export { MenuChange }
3.动态添加
/* @/store/modules/permission.js */
import { constantRoutes, newAsyncRoutes } from '@/router'
import router from '@/router'
// import { resetRouter } from '@/router'
import { promission } from '@/api/user'
import { MenuChange } from '@/utils/dyRouter'
// import * as Types from '@/store/mutation-types'
// import store from '@/store'
const state = {
Routes: [...constantRoutes] // 静态路由+动态路由
}
const mutations = {
setRoutes(state, value) {
state.Routes = value
},
removeRoutes(state, value) {
state.Routes = [...constantRoutes]
}
}
const actions = {
getUserRoutes({ commit }, form) {
return new Promise((resolve, reject) => {
/* 权限路由返回接口 */
权限路由返回接口.({})
.then(res => {
/* 查询后台并且返回左侧菜单数据并把数据添加到路由 */
const obj = res.data
const treeMenuData = MenuChange(obj) // 后端返回路由处理
// console.log(treeMenuData, 'treeMenuData')
// 这个地方是处理侧边栏子路由只有一个时父路由名称不会显示的问题。
treeMenuData.forEach((item, index) => {
if (item.children.length > 1) {
item.redirect = `/${item.title}/${item.children[0].path}`
}
item.children.forEach((itm, idx) => {
if (itm.children && itm.children.length > 1) {
itm.redirect = `/${item.title}/${itm.title}/${itm.children[0].path}`
}
})
})
// console.log(treeMenuData, 'treeMenuData2')
const _menu = [
...treeMenuData,
...newAsyncRoutes
// component: () => import('@/views/404.vue'),
]
commit('setRoutes', [...constantRoutes, ..._menu]) // 将路由放置缓存中
router.addRoutes(_menu) // 废弃 只是会警告但是还可以使用 数组形式
// console.log(_menu, '_menu')
resolve()
})
.catch(error => {
reject(error)
})
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
4.Layout/Sidebar
export default {
computed:{
routes(){
// 侧边栏
// return this.$router.options.routes
return this.$store.state.permission.Routes
}
}
}