vue实现管理端框架结构(路由页面 ,左边导航,面包屑导航,layout布局)
路由:
import Vue from "vue";
import VueRouter from "vue-router";
import { Message } from "element-ui";
import local from "@/utils/local.js";
Vue.use(VueRouter);
// 路由配置
const routes = [
//访问时自动跳登陆页
{ path: "/", redirect: "/login" },
//登陆页
{
path: "/login",
component: () => import("@/views/login/LoginView.vue"),
mete: { role: ["super"] },
},
// 首页
{
path: "/index",
component: () => import("../views/index/LayOut.vue"),
meta: { role: ["super", "normal"], title: "后台首页" },
// isMenu: true, //声明要做导航的路由
icon: "el-icon-s-home",
children: [
{
path: "",
component: () => import("@/views/index/IndexView.vue"),
meta: { role: ["super", "normal"] },
},
],
},
//商品管理
{
path: "/goods",
component: () => import("@/views/index/LayOut.vue"),
meta: { role: ["super", "normal"], title: "商品管理" },
// isMenu: true, //声明要做导航的路由
icon: "el-icon-s-goods",
redirect: "/goods/list",
children: [
{
path: "/goods/list",
component: () => import("@/views/goods/GoodsList.vue"),
meta: { role: ["super", "normal"], title: "商品列表" },
// isMenu: true,
},
{
path: "/goods/add",
component: () => import("@/views/goods/GoodsAdd.vue"),
meta: { role: ["super", "normal"], title: "添加商品" },
// isMenu: true,
},
{
path: "/goods/category",
component: () => import("@/views/goods/GoodsCategory.vue"),
meta: { role: ["super", "normal"], title: "商品分类" },
// isMenu: true,
},
{
path: "/goods/edit",
component: () => import("@/views/goods/GoodsEdit.vue"),
meta: { role: ["super", "normal"], title: "修改商品" },
},
],
},
//订单管理
{
path: "/order",
component: () => import("../views/index/LayOut.vue"),
meta: { role: ["super", "normal"], title: "订单管理" },
// isMenu: true, //声明要做导航的路由
icon: "el-icon-s-order",
children: [
{
path: "",
component: () => import("@/views/order/OrderView.vue"),
meta: { role: ["super", "normal"] },
},
],
},
//店铺管理
{
path: "/shop",
component: () => import("../views/index/LayOut.vue"),
meta: { role: ["super"], title: "店铺管理" },
// isMenu: true,
icon: "el-icon-s-shop",
children: [
{
path: "",
component: () => import("@/views/shop/ShopView.vue"),
meta: { role: ["super"] },
},
],
},
//账号管理
{
path: "/account",
component: () => import("../views/index/LayOut.vue"),
meta: { role: ["super"], title: "账号管理" },
// isMenu: true, //声明要做导航的路由
redirect: "/account/list",
icon: "el-icon-user-solid",
children: [
{
path: "/account/list",
component: () => import("@/views/account/AccountList.vue"),
meta: { role: ["super"], title: "账号列表" },
// isMenu: true,
},
{
path: "/account/add",
component: () => import("@/views/account/AccountAdd.vue"),
meta: { role: ["super"], title: "添加账号" },
// isMenu: true,
},
{
path: "/account/changepassword",
component: () => import("@/views/account/ChangePassword.vue"),
meta: { role: ["super"], title: "修改密码" },
// isMenu: true,
},
{
path: "/account/personal",
component: () => import("@/views/account/PersonalView.vue"),
meta: { role: ["super"], title: "管理员信息" },
// isMenu: true,
},
],
},
//销售统计
{
path: "/count",
component: () => import("../views/index/LayOut.vue"),
meta: { role: ["super"], title: "销售统计" },
// isMenu: true,
icon: "el-icon-pie-chart",
redirect: "/count/goods",
children: [
{
path: "/count/goods",
component: () => import("@/views/count/CountGoods.vue"),
meta: { role: ["super"], title: "销售统计" },
// isMenu: true,
},
{
path: "/count/order",
component: () => import("@/views/count/CountOrder.vue"),
meta: { role: ["super"], title: "订单统计" },
// isMenu: true,
},
],
},
];
//防止访问重复页面时报错
// 获取原型对象push函数
const originalPush = VueRouter.prototype.push;
// 修改原型对象中的push函数
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch((err) => err);
};
const router = new VueRouter({
routes,
});
//路由守卫
router.beforeEach(function (to, from, next) {
// 默认访问到登录页
if (to.path === "/login") {
next(); //登陆页面直接放行
} else {
let token = local.get("token");
// console.log("token111111111111", token);
if (token) {
if (to.meta.role.includes(local.get("role"))) {
next();
} else {
next("/login");
}
} else {
Message.error("警察叔叔还有三秒到达战场,请稍后...");
next({ path: "/login" });
}
}
});
export default router;
左边导航:
<template>
<div class="left-nav">
<div class="title">
<el-avatar :size="50" :src="imgUrl"></el-avatar>
<h1>玩家外卖</h1>
</div>
<!-- router是开启路由模式,index是作为path一样的进行跳转 -->
<!-- unique-opened默认只展示一个子菜单 -->
<!-- :default-active="$route.path" 当前路由是哪个就激活那个 -->
<el-menu
router
:default-active="$route.path"
background-color="#48ac79"
text-color="#fff"
active-text-color="#26da6f"
unique-opened
>
<div v-for="v in rolemenus" :key="v.indedivx">
<!-- 可以展开 -->
<el-submenu v-if="v.children" :index="v.index">
<!-- 一级标题 -->
<template slot="title">
<i :class="v.icon"></i>
<span>{{ v.tit }}</span>
</template>
<!-- 二级标题 -->
<el-menu-item
v-for="child in v.children"
:key="child.index"
:index="child.index"
>{{ child.tit }}</el-menu-item
>
</el-submenu>
<!-- 不可以展开 -->
<el-menu-item v-else :index="v.index">
<i :class="v.icon"></i>
<span slot="title">{{ v.tit }}</span>
</el-menu-item>
</div>
</el-menu>
</div>
</template>
<script>
import { userInfo } from "@/api/user.js";
import local from "@/utils/local.js";
export default {
data() {
return {
list: [
// 首页
{
index: "/index",
icon: "el-icon-s-home",
tit: "后台首页",
role: ["super", "normal"],
},
// 订单管理
{
index: "/order",
icon: "el-icon-s-order",
tit: "订单管理",
role: ["super", "normal"],
},
// 商品管理
{
index: "/goods",
icon: "el-icon-s-goods",
tit: "商品管理",
role: ["super", "normal"],
children: [
{ index: "/goods/add", tit: "添加商品" },
{ index: "/goods/list", tit: "商品列表" },
{ index: "/goods/category", tit: "商品分类" },
],
},
// 店铺管理
{
index: "/shop",
icon: "el-icon-s-shop",
tit: "店铺管理",
role: ["super"],
},
// 账号管理
{
index: "/account",
icon: "el-icon-user-solid",
tit: "账号管理",
role: ["super"],
children: [
{ index: "/account/add", tit: "添加账号" },
{ index: "/account/list", tit: "账号列表" },
{ index: "/account/changepassword", tit: "修改密码" },
{ index: "/account/personal", tit: "管理员信息" },
],
},
// 销售统计
{
index: "/count",
icon: "el-icon-pie-chart",
tit: "销售统计",
role: ["super"],
children: [
{ index: "/count/goods", tit: "商品统计" },
{ index: "/count/order", tit: "订单统计" },
],
},
],
//默认头像,远程地址直接使用,本地地址需要(import)引入后再使用
imgUrl:
"https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png",
};
},
async created() {
//获取管理员信息
let res = await userInfo();
this.imgUrl = res.data.imgUrl;
//绑定事件,接收头像参数,实现头像联动
this.$bus.$on("upImg", (url) => {
this.imgUrl = url; //注意this会被改指向,所以要用箭头函数
});
},
computed: {
// 权限控制
rolemenus() {
// 从list数组中过滤,按照角色返回相应的菜单栏
let newarr = this.list.filter((v) => {
return v.role.includes(local.get("role"));
});
return newarr;
},
},
};
</script>
<style lang="scss" scoped>
.title {
display: flex;
align-items: center;
justify-content: space-around;
align-content: center;
padding: 15px 0;
img {
width: 50px;
border-radius: 50%;
}
h1 {
text-align: center;
font-size: 18px;
// color: #26da6f;
color: #fff;
cursor: pointer;
}
}
:deep(.el-menu) {
border: 0;
background-color: #48ac79;
}
.left-nav {
background-color: #48ac79;
height: 100%;
}
:deep(.el-submenu__title i) {
color: #04f759;
}
.el-menu-item i {
color: #04f759;
}
:deep(.el-breadcrumb__separator) {
color: #48ac79;
z-index: 9;
}
</style>
面包屑导航:
<template>
<div class="header">
<!-- 面包屑导航 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item to="/login" v-if="$route.path !== '/index'"
>后台首页</el-breadcrumb-item
>
<el-breadcrumb-item v-for="(v, i) in menuArr" :to="v.path" :key="i">{{
v.name
}}</el-breadcrumb-item>
</el-breadcrumb>
<!-- 管理员信息 -->
<el-dropdown @command="jump">
<span class="el-dropdown-link">
欢迎{{ account }}登录
<el-avatar :size="50" :src="imgUrl"></el-avatar>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="/account/personal"
>个人信息</el-dropdown-item
>
<el-dropdown-item command="/logout">退出登陆</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
import local from "@/utils/local.js";
import { userInfo } from "@/api/user.js";
export default {
data() {
return {
//默认头像,远程地址直接使用,本地地址需要(import)引入后再使用
imgUrl:
"https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png",
//面包屑导航数据
menuArr: [],
//管理员名称
account: "",
};
},
methods: {
//点击下拉菜单时执行事件处理函数
jump(path) {
if (path === "/logout") {
local.clear();
this.$router.push("/login");
} else {
this.$router.push(path);
}
},
// 获取面包屑导航联动 matched是匹配所有的符合路由
render() {
let arr = this.$route.matched.filter((v) => {
return v.meta.title;
});
this.menuArr = arr.map((v) => {
return { name: v.meta.title, path: v.path };
});
},
},
// 刷新过后再次渲染
async created() {
this.render();
//获取管理员信息
let res = await userInfo();
// console.log(res);
local.set("userinfo", res.data); //将管理员信息存储到本地
this.account = res.data.account;
this.imgUrl = res.data.imgUrl;
//绑定事件,接收头像参数,实现头像联动
this.$bus.$on("upImg", (url) => {
this.imgUrl = url; //注意this会被改指向,所以要用箭头函数
});
},
// 监听数据改变
watch: {
"$route.path"() {
this.render();
},
},
};
</script>
<style lang="scss" scoped>
.header {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
}
.el-dropdown-link {
color: #fff;
}
.el-avatar {
vertical-align: middle;
}
</style>
layout布局:
<template>
<div class="layout">
<el-container>
<!-- 左边导航 -->
<el-aside width="200px">
<left-nav></left-nav>
</el-aside>
<el-container>
<!-- 头部 -->
<el-header>
<top-header></top-header>
</el-header>
<!-- 主体-->
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
components: {
LeftNav: () => import("@/components/LeftNav.vue"),
TopHeader: () => import("@/components/TopHeader.vue"),
},
};
</script>
<style lang="scss" scoped>
.layout {
height: 100vh;
}
.el-header {
width: 100%;
padding: 0 15px;
box-sizing: border-box;
flex-shrink: 0;
background: #48ac79;
}
:deep(.el-breadcrumb__item span) {
color: #fff;
}
.layout > .el-container {
height: 100%;
}
.el-aside {
background-color: #d3dce6;
}
.el-main {
background-color: #e9eef3;
}
</style>
注意:web端项目框架构建!!!!
推荐阅读:
扫描二维码,在手机上阅读