【记录:Vue2配合PHP后端返回路由结构进行改造并动态添加路由】

后端技术: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
 	 	}
 	}
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值