vue动态路由来生成系统菜单(一)
先说下功能吧,就是菜单通过动态路由进行渲染出来,而不是路由配置写死来实现。虽然网上已经有各种帖子来介绍,但我还是折腾了快2天才搞定。直接上代码吧<template><div class="go-page go-manage-page&a
·
先说下功能吧,就是菜单通过动态路由进行渲染出来,而不是路由配置写死来实现。虽然网上已经有各种帖子来介绍,但我还是折腾了快2天才搞定。逻辑非常简单,思路也简单就是从数据库查下路由配置信息,构建成路由结构交给addRoutes。最要命的是require赖加载不支持变量,折腾一天才搞出来。
直接上代码吧
<template>
<div class="go-page go-manage-page">
<!--头部-->
<ManageHeader moduleName="UnitTabSetHomePage" :routerId="manageRouterId" :tabsetId="adminTabsetId"
:userName="userName"></ManageHeader>
<!--左侧菜单-->
<ManageLeftMenu :menuState="menuState" :menus="menus" :routerId="manageRouterId"
:tabsetId="adminTabsetId"></ManageLeftMenu>
<!--tabset区块-->
<AdminTabset :menuState="menuState" :winResize="winResize" :id="adminTabsetId" :routerId="manageRouterId"
:defaultPage="adminMainPageId"></AdminTabset>
<!--首页内容-->
<div :id="adminMainPageId" style="display: none">
<AdminMainPage :tabsetId="adminTabsetId" :routerId="manageRouterId" :menus="menus"></AdminMainPage>
</div>
<!--隐藏路由-->
<div style="visibility: hidden;position: absolute;left: 0;top:0;" class="h100b" :id="manageRouterId">
<router-view class="h100b router-view"></router-view>
</div>
<HomePageWinArea></HomePageWinArea>
</div>
</template>
<script>
import {mapState, mapActions} from 'vuex'
import AdminMainPage from '../commonComponents/AdminMainPage';
import ManageHeader from '../commonComponents/ManageHeader';
import ManageLeftMenu from '../commonComponents/ManageLeftMenu';
import AdminTabset from '../commonComponents/AdminTabset';
import HomePageWinArea from '../commonComponents/HomePageWinArea';
import UnitTabSetHomePage from '../../../pages/manageHomePage/UnitTabSetHomePage';
import DynamicRouterUtils from '../commonJs/dynamicRouterUtils.js';
GoingUtils.mainHeight = $(document.body).height() - 78;
export default {
created: function () {
let vueObj = this;
//从缓存中获取到当前用户的菜单信息
let unitManageMenus = StorageUtils.getSessionItem("unitManageMenus");
if (AssertUtils.isNotEmpty(unitManageMenus)) {
let menusTemp = JSON.parse(unitManageMenus);
vueObj.$store.commit($M('SET_MENUS', 'UnitAdminStore'), menusTemp);
// 加载路由
DynamicRouterUtils._loadRouters(menusTemp, vueObj, UnitTabSetHomePage);
} else {
//如果缓存中不存在 则从数据库中查询出用户的菜单信息
let queryCommand = new QueryCommand("/go-framework/menu/queryMenuAclInfo/erp");
//执行查询操作
queryCommand.executeAsyncQuery({}, function (backData) {
if (backData != null) {
let secondItems = backData[0].children;
let menus = backData[0].children;
vueObj.$store.commit($M('SET_MENUS', 'UnitAdminStore'), menus);
//缓存起来
StorageUtils.addSessionItem("unitManageMenus", JSON.stringify(menus));
//动态添加路由信息
DynamicRouterUtils._loadRouters(menus, vueObj, UnitTabSetHomePage);
}
}, () => {
}, "json");
}
},
name: 'homePage',
computed: {
//tabset对象的id
adminTabsetId(){
return "unitTabSetHomePage"
},
//默认首页div的id
adminMainPageId(){
return GoingUtils.getUUid();
},
//路由div的id
manageRouterId(){
return GoingUtils.getUUid();
},
...mapState({
winResize: state => state.UnitAdminStore.winResize,
menuState: state => state.UnitAdminStore.menuState,
menus: state => state.UnitAdminStore.menus,
userName: state => state.UnitAdminStore.userName,
})
},
mounted(){
$.getScript("/static/plugin/Sortable.js", function () {
});
let vueObj = this;
//加载当前用户信息
this.$store.dispatch('getCurrentUser', function (backData) {
vueObj.$store.commit($M("GET_CURRENT_USER", "UnitAdminStore"), backData);
});
//将routerId缓存起来
this.$store['mainRouterId'] = this.manageRouterId;
//如果界面大小发生变更
$(window).resize(function () {
//修改state状态,触发控件变化
vueObj.$store.commit($M('SET_WIN_RESIZE', 'UnitAdminStore'));
});
//设置滚动条样式
$(".dhx_cell_cont_tabbar").css("overflow", 'auto')
},
beforeDestroy(){
},
components: {
HomePageWinArea,
AdminMainPage,
ManageHeader,
ManageLeftMenu,
AdminTabset,
}
}
</script>
关键就是这句话,来动态构建路由
//动态添加路由信息
DynamicRouterUtils._loadRouters(menus, vueObj, UnitTabSetHomePage);
DynamicRouterUtils的代码如下
import Error404 from '../../sysPage/system/Error404';
//从menus里面过滤出页面信息
function _getPagesFromMenus(menus, pages) {
if (AssertUtils.isNotNull(menus)) {
menus.forEach(function (item, index) {
if (item.type === "page") {
pages.push(item);
}
if (AssertUtils.isNotNull(item.children) && AssertUtils.isArray(item.children)) {
_getPagesFromMenus(item.children, pages);
}
})
}
}
function getViews(path) {
path=path.replace(".vue","")+".vue";
path = path.replace("/pages", ".");
let context = require.context('@/pages', true, /^\/*.*\.vue/);
return resolve => {
require.ensure([], (require) => {
resolve(context(path))
})
}
}
var getLastUrl=(str,yourStr)=>str.slice(str.lastIndexOf(yourStr))//取到浏览器出现网址的最后"/"出现的后边的字符
//根据菜单生成路由
function _getRouters(menus) {
let pages = [];
_getPagesFromMenus(menus, pages);
const aRouter = [];let routerUrls=[];let routerJsons={};
pages.forEach(function (item, index) {
let {id, componentUrl, moduleName, name, url, children}=item;
//如果是存在 组件url 才需要生成路由配置 而且url是/开头的
const oRouter = {
path: url,
componentUrl:componentUrl,
component: getViews(componentUrl),
name: url,
id: id
}
aRouter.push(oRouter);
routerJsons[getLastUrl(url,'/')]=oRouter;
routerUrls.push(getLastUrl(url,'/'));
})
StorageUtils.addSessionItem("routerUrls", routerUrls.join(";"));
StorageUtils.addSessionItem("routerJsons", JSON.stringify(routerJsons));
return aRouter;
}
const constantRouterMap = [
//404
{path: '/404',component: Error404},{ path: '*', redirect: '/404' }//重定向到404
]
export default {
getRouterByUrl(lastUrl,UnitTabSetHomePage,router){
let routerJsons=JSON.parse(StorageUtils.getSessionItem("routerJsons"));
let routerObj=routerJsons[lastUrl];
//根据组件的url 来获取组件对象
let {componentUrl}=routerObj;
routerObj["component"]=getViews(componentUrl);
if(AssertUtils.isNotNull(routerObj)){
router.addRoutes( constantRouterMap.concat([
{
path: '/UnitTabSetHomePage',
name: "tabSetHomePage",
component: UnitTabSetHomePage,
children: [routerObj]
}]))
}
return routerObj;
},
//动态加载相应的路由 根据菜单信息
_loadRouters(menus, vueObj, UnitTabSetHomePage) {
//根据菜单获取路由信息
let routers = _getRouters(menus);
//动态添加路由信息
if (AssertUtils.isNotNull(routers) && AssertUtils.isArray(routers)) {
vueObj.$router.addRoutes(constantRouterMap.concat([
{
path: '/UnitTabSetHomePage',
name: "tabSetHomePage",
component: UnitTabSetHomePage,
children: routers
}]));
}
}
}
大家千万别去研究require(变量)这种方式了,我都折腾了一天,各种法子都试了,没一个是可以用的,还是通过require.context 去取吧。虽然可能性能不是最佳的,但总比写死路由来的可靠。由于本人的git还没弄好,后续我会把项目放到git上去,目前需要代码的可以qq【289028210】我。
到这并没有完全搞定,你会发现去刷新子界面的时候页面是空白。没法点击f5去刷新了,而且在子路由界面下,修改操作后界面也是空白,请看下一节对这个进行处理。
更多推荐
已为社区贡献8条内容
所有评论(0)