管理系统中后端动态路由实现
1.输入密码登录跳转登录后的详情页面
methods:{
submitLogin(){
this.$refs.loginForm.validate((valid) => {
if (valid) {
if(this.loginForm.username == 'admin' && this.loginForm.password == 'ssssss'){
sessionStorage.setItem('isAuth',true);
let path = '/home';
if(this.$route.query.redirect) {
path = this.$route.query.redirect
}
this.$router.push({
path:path
});
}else {
sessionStorage.setItem('isAuth',false);
this.$router.push('/');
this.loginForm.username = '';
this.loginForm.password = '';
}
} else {
this.$message.error('登录出错请重新输入');
return false;
}
});
}
},
2.路由文件代码主要实现动态添加路由功能和导航守卫功能(实现后端返回路由表示一定和后端商量好路由表结构),因为有其他地方需要使用后端返回的路由表所以要将其存储在本地sessionStorage.setItem方法实现
import Vue from 'vue'
import VueRouter from 'vue-router';
import Layout from '@/components/Home/index.vue';
import {menu} from '@/api/login'
import {createRoute} from '@/router/getRoutes'
Vue.use(VueRouter);
const routes = [
{
path:'/',
name: 'login',
component: () => import('../components/LogIn')
},
{
path:'/home',
name:'Home',
component: Layout,
redirect: '/home/aaaa',
children:[],
},
]
const router = new VueRouter({
mode: 'history',
routes,
})
router.beforeEach((to, from, next) => {
if (to.path === '/') return next()
let token = window.sessionStorage.getItem('isAuth')
if (!token){
next("/");
}else {
if(routes[1].children.length == 0) {
menu().then((res)=>{
sessionStorage.setItem(
"asyncRoutes",
JSON.stringify(res.data.items)
);
const {items} = res.data;
createRoute(items);
})
}
next();
}
})
export default router;
我这边的接口是用node实现的也可以用mock.js(后端返回前端的路由表结构)
app.get("/search/users2", function (req, res) {
res.json({
items: [
{
path: "aaaa",
name: "Index",
component: "A/index",
meta: {
menuName: "首页",
icon: "el-icon-s-home",
},
},
{
path: "todo",
name: "Todo",
component: "B/index",
meta: {
bread: ["待办事项"],
menuName: "待办事项",
icon: "el-icon-chat-dot-square",
},
},
{
path: "my",
name: "My",
component: "C/index",
meta: {
bread: ["个人中心"],
menuName: "个人中心",
icon: "el-icon-user",
},
},
{
path: "/account",
name: "Account",
component: "Layout",
meta: {
menuName: "账户管理",
icon: "el-icon-coin",
},
children: [
{
path: "all",
name: "AccountAll",
component: "D/A/index",
meta: {
menuName: "所有人员",
icon: "el-icon-user",
},
},
{
path: "business",
name: "AccountBusiness",
component: "D/B/index",
meta: {
menuName: "业务人员",
icon: "el-icon-phone-outline",
},
},
{
path: "audit",
component: "D/C/index",
name: "AccountAudit",
meta: {
menuName: "审核人员",
icon: "el-icon-s-check",
},
},
],
},
],
});
});
路由表中 component: "A/index"是一个字符串,并且有的路由有子路由所以要处理一下处理的方法是createRoute代码如下
import router from "./index";
export const createRoute = (items) =>{
items.forEach((item) => {
if (!item.component) {
return;
}
const temp = {
path: item.path,
name: item.name,
component: () => import(`@/components/${item.component}.vue`)
}
router.addRoute("Home",temp);
if (item.children) {
createRoute(item.children);
}
});
}
3.前端element-ui侧边栏使用前面存储到本地的路由表代码如下
<template>
<div>
<el-container style="height: 100vh; ">
<el-aside width="250px">
<el-menu
:default-active="$route.path"
class="el-menu-vertical-demo"
unique-opened
router
>
<menu-item
v-for="item in menus"
:key="item.path"
:menu="item"
></menu-item>
</el-menu>
</el-aside>
<el-container>
<el-main >
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import menuItem from "./menuItem.vue";
export default {
components: { menuItem },
data() {
return {
menus: "",
};
},
created() {
this.menus = JSON.parse(sessionStorage.getItem("asyncRoutes"));
},
};
</script>
<style>
.el-header {
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
menuItem.vue文件代码
<template>
<div>
<el-submenu :index="menu.path" v-if="menu.children">
<template slot="title">
<i :class="menu.meta.icon"></i>
<span>{{ menu.meta.menuName }}</span>
</template>
<menu-item
v-for="item in menu.children"
:key="item.path"
:menu="item"
></menu-item>
</el-submenu>
<el-menu-item :index="`/home/${menu.path}`" v-else>
<i :class="menu.meta.icon"></i>
<span slot="title">{{ menu.meta.menuName }}</span>
</el-menu-item>
</div>
</template>
<script>
export default {
props: {
menu: {
type: Object,
required: true,
},
},
name: "menuItem",
};
</script>
以上基本实现了后端动态路由,有不对的地方欢迎指正以免误导他人,这篇文章也参考了网上许多人的代码https://blog.csdn.net/weixin_56611064/article/details/117449805