vue全家桶搭建后台系统(小菜鸟篇二)

困扰的问题之一,就是根据后台返回的菜单动态生成路由。
需要实现的效果
在这里插入图片描述
后端返回菜单格式:
{
“id”:45,
“text”:“项目管理”,

“children”:[
{
“id”:47,
“text”:“xx管理”,
“pid”:45,
“leaf”:true,

            },{
			}
         
        ]
    },

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200311101856785.png
功能点:登录之后请求当前账号有权限的菜单,顶部为主菜单,左侧为对应主菜单下的子菜单
根据菜单树动态生成路由,然后通过addRoutes添加路由。
解决的问题:刷新之后添加的路由会消失

//router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import store from '@/store'
import login from '@/view/Login.vue'
//解决Element-ui 点击多次路由会报错:NavigationDuplicated {_name: “NavigationDuplicated”, name: “NavigationDuplicated”}
const originalPush = Router.prototype.push;
Router.prototype.push = function push(location) {
	return originalPush.call(this, location).catch(err => err)
}
Vue.use(Router)

let router = new Router({
	routes: [{
		path: '/login',
		name: 'login',
		meta: {
			requireAuth: false
		},
		component: login
	}]
})
// 拦截登录,token验证
router.beforeEach((to, from, next) => {
	if (to.meta.requireAuth === undefined) {
	//判断是否登录
		if (store.state.user.isLogin) {
			next()
		} else {
			next({
				path: '/login'
			})
		}
	} else {
		next()
	}
})
export default router

//登录点击事件   登录成功之后 
//login.js
this.setMenuAction().then(res => {
	var routes = [],
		menu = res.data;
	routes = routes.concat(generateRouter(menu, []));
	routes = handleRoute.mergeRoutes(routes);
	// 防止重复配置相同路由
	if (this.$router.options.routes.length <= 1) {
		this.$router.addRoutes(routes);
		// this.$router不是响应式的,所以手动将路由元注入路由对象
		this.$router.options.routes.push(routes);
	}
});
	//vuex store.js
	//存储menu和当前子菜单
	setMenuAction(context, params) {
			return new Promise((resolve, reject) => {
				getMenuTree(params).then(result => {
					context.commit('setMenu', result.data);
					context.commit('setCurrentMenu',result.data[0].children);
					resolve(result);
				})

			})
		}
//common.js
//根据菜单生成一个routes数组  具体处理规则根据自己项目处理
export function generateRouter(data = [], router) {
	for (let i = 0; i < data.length; i++) {
		if (data[i].leaf) {
			var path = 'view/'+data[i].identifier.replace(/\_/g,'/');
			router.push({
				name: data[i].identifier,
				path: path,
				component: resolve => require(['@/' + path + '.vue'], resolve)
			});
		} else {
			generateRouter(data[i].children, router);
		}
	}
	console.log(router)
	return router;
}

//合并本地路由与远程路由
//本地路由,具体根据项目配置
const routes = [{
	path: '/',
	name: 'home',
	component: (resolve) => require(['@/view/Main.vue'], resolve),
	children: []
}]
export default {
	/**
	 * 合并远程路由到本地路由
	 * @param: subList [Array] 远程路由列表
	 * @param: routes [Array] 本地路由列表
	 * */
	mergeRoutes(subs) {
		if (subs) {
			// var routeArr = generateRouter(subs, []);
			routes[0].children = subs;
		}
		console.log(routes)
		return routes;

	}
}
//刷新之后路由消失的问题  登录的时候将路由或者菜单存储到本地  在App.vue
//这里是直接去拿了存储在store里面的menu又生成了一次routes然后添加   更简单的做法是直接将路由存储去获取
export default {
	name: 'App',
	computed: {
		...mapGetters(['isLogin', 'routeList', 'menu'])
	},
	created() {
		if (this.$router.options.routes.length <= 1 && this.$store.state.menu.routeList.length) {
			var routes = [],
				menu = this.menu ? this.menu : [];
			routes = routes.concat(generateRouter(menu ? menu : [], []));
			routes = handleRoute.mergeRoutes(routes);
			this.$router.addRoutes(routes);
			this.$router.options.routes.push(routes);
		}
		
	}
};

差不多就到这啦,就当自己的一个笔记啦。能力问题,写的不够优化的地方大家多多包涵、指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值