The project needs to be a management background. I have used ele before and I think it is good, so this project selection, I still use element-ui
The project architecture element-ui vue vuex vue-router axios also has a rich text wangEditor (later I saw a vue-admin?), the architecture is similar. Later, I thought about it and I packaged it myself, and I also learned from the packages of many big brothers.
First, the first block, navMenu
<template>
<div id="navbar">
<el-menu :default-active="currentRoute"
:default-openeds="opens"
class="el-menu-vertical-demo"
router
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse">
<!-- 有子菜单 -->
<template v-for="(first,f_index) in navData">
<el-submenu :index="first.index"
:key="`menu0_${f_index}`"
v-if="first.second.length>0">
<template slot="title"
v-if="first.title">
<i :class="first.icon"></i>
<span slot="title">{{first.title}}</span>
</template>
<el-menu-item-group v-for="(second,s_index) in first.second"
:key="s_index">
<span slot="title"
v-if="second.title">{{second.title}}</span>
<el-menu-item :index="second_child.index"
v-for="(second_child,second_c_index) in second.child"
:key="second_c_index">{{second_child.content}}</el-menu-item>
</el-menu-item-group>
<div v-for="(second,s_index) in first.second"
:key="s_index+'a'">
<el-submenu :index="third.index"
v-for="(third,th_index) in second.third"
:key="th_index">
<span slot="title">{{third.title}}</span>
<el-menu-item :index="third_child.index"
v-for="(third_child,third_c_index) in third.child"
:key="third_c_index">{{third_child.content}}</el-menu-item>
</el-submenu>
</div>
</el-submenu>
<!-- 没有子菜单 -->
<el-menu-item :index="first.index"
:key="`menu0_${f_index}`"
v-if="first.second.length==0">
<i class="el-icon-menu"></i>
<span slot="title">{{first.title}}</span>
</el-menu-item>
</template>
</el-menu>
</div>
</template>
<script>
export default {
data() {
return {
isCollapse: false,
currentRoute: "",
opens: [],
navData: [
{
index: "/article",
title: "内容",
icon: "el-icon-location",
second: [
{
title: "这里全是知识库相关",
child: [
{
index: "/article/list",
content: "知识文章"
},
{
index: "/article/sort",
content: "分类管理"
},
{
index: "/article/organize",
content: "机构管理"
},
{
index: "/article/comment",
content: "评论管理"
},
{
index: "/article/report",
content: "举报管理"
}
]
}
// {
// third: [
// {
// title: "举报相关",
// index: "",
// child: [
// {
// index: "",
// content: "已举报"
// },
// {
// index: "",
// content: "已举报"
// }
// ]
// }
// ]
// }
]
},
{
index: "/hospital",
title: "医院医生",
icon: "el-icon-menu",
second: [
{
title: "医院医生相关信息",
child: [
{
index: "/hospital/hospitalList",
content: "医院库"
},
{
index: "/hospital/doctorList",
content: "医生库"
},
{
index: "/hospital/doctorTeamList",
content: "团队医生"
},
{
index: "/hospital/doctorApply",
content: "申请入住"
}
]
}
]
},
// {
// index: "3",
// title: "医生问答",
// icon: "el-icon-menu",
// second: []
// },
// {
// index: "4",
// title: "申请入住",
// icon: "el-icon-menu",
// second: []
// },
// {
// index: "5",
// title: "患者列表",
// icon: "el-icon-menu",
// second: []
// },
{
index: "/community",
title: "社区管理",
icon: "el-icon-menu",
second: [
{
child: [
{
index: "/community/circleList",
content: "圈子列表"
},
{
index: "/community/invitationList",
content: "帖子列表"
},
{
index: "/community/commentList",
content: "评论列表"
},
{
index: "/community/report",
content: "举报管理"
}
]
}
]
},
// {
// index: "7",
// title: "评论审批",
// icon: "el-icon-menu",
// second: []
// },
{
index: "8",
title: "活动设置",
icon: "el-icon-menu",
second: [
{
child: [
{
index: "/activity/banner",
content: "banner设置"
}
]
}
]
},
{
index: "/shop",
title: "商品管理",
icon: "el-icon-menu",
second: [
{
child: [
{
index: "/shop/list",
content: "商品列表"
}
]
}
]
},
{
index: "10",
title: "订单信息",
icon: "el-icon-menu",
second: [
{
child: [
{
index: "/order/list",
content: "订单列表"
}
]
}
]
}
]
};
},
created() {
this.currentRoute = this.$route.path;
this.opens = [];
this.opens[0] = this.currentRoute.substring(
this.currentRoute.indexOf("/"),
this.currentRoute.lastIndexOf("/")
);
console.log(this.opens);
},
mounted() {},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
};
</script>
<style lang="less" scoped>
#navbar {
width: 200px;
.el-menu-vertical-demo:not(.el-menu--collapse) {
min-height: 100vh;
overflow-y: scroll;
}
}
</style>
At the beginning, I wrote it myself, and I didn't read the official layout, so it is recommended to use the official left and right layout. I tried it, and it was good. After all, semantics is the meaning of H5.
There is a small problem here, that is, whenever you jump, the menu is closed by default, and then expanded. That is, every time a router is jumped, the menu will be closed first, and then expanded, and the effect is not very good. After looking for a long time, I saw a property
My approach is to intercept the path of the route, and then assign a value to the first-layer route, which finally solves the problem. If there are other ways, please communicate.
The following is the layout layout
<template>
<div class="layout">
<div class="main-wrapper">
<div class="main-left">
<Navbar></Navbar>
</div>
<div class="main-right">
<div class="main-right-wrapper">
<div class="main-right-title">{{pageTitle}}</div>
<slot>
<router-view />
</slot>
</div>
</div>
</div>
</div>
</template>
<script>
import Navbar from "../components/navbar";
// import "element-ui/lib/theme-chalk/display.css";
export default {
name: "layout",
components: {
Navbar
},
data() {
return {
isCollapse: false,
docWidth: document.body.clientWidth,
pageTitle: ""
};
},
computed: {},
mounted() {
this.pageTitle = document.title;
}
};
</script>
<style lang="less">
.layout {
width: 100vw;
height: 100vh;
.main-wrapper {
display: flex;
> div {
&:last-of-type {
flex-grow: 1;
}
}
}
.main-right-title {
background: #fff;
font-weight: bold;
padding: 20px;
}
.main-right-wrapper {
height: 100vh;
padding: 20px;
background: #f2f2f2;
overflow: scroll;
> div {
background: #fff;
padding: 20px;
}
}
}
</style>
The page call is as follows:
<template>
<layout>
<div id=''>
</div>
</layout>
</template>
<script>
export default {
components: {},
props: {},
data() {
return {};
},
mounted() {},
methods: {}
};
</script>
<style lang="less" scoped>
</style>