Commit 2b5e9b99 authored by 吴婷慧's avatar 吴婷慧

菜单栏处理完成

parent 43c6176e
......@@ -8,7 +8,7 @@
<title><%= htmlWebpackPlugin.options.title %></title>
<script
type="text/javascript"
src="//at.alicdn.com/t/font_3020450_3q020khoouw.js"
src="//at.alicdn.com/t/font_3020450_fmrwd9gemcl.js"
></script>
</head>
<body>
......
import Vue from "vue";
import { Button, Input, notification } from "ant-design-vue";
import { Button, Input, notification, menu, dropdown } from "ant-design-vue";
export default () => {
let els = [Button, Input, notification];
let els = [Button, Input, notification, menu, dropdown];
// 注册
els.forEach((item) => {
Vue.use(item);
......
<template>
<div class="icon-class" :style="`font-size:${size}px`" @click="clickEvent">
<div
class="icon-class"
:style="`font-size:${size}px`"
@click.stop="clickEvent"
>
<svg class="icon" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
......
......@@ -45,6 +45,6 @@ const router = new VueRouter({
routes,
});
RouterGuard(VueRouter);
RouterGuard(VueRouter, router);
export default router;
export default [
{
icon: "ssiuser",
path: "customer",
title: "客户信息",
children: [
{
path: "/customer",
title: "客户信息明细",
},
{
path: "",
title: "新建客户信息",
},
],
},
{
icon: "ssimanage_msg",
path: "/welfare",
title: "福利信息管理",
children: [],
},
{
icon: "ssimanage",
path: "pre-auth",
title: "预授权信息管理",
children: [
{
path: "/pre-auth",
title: "预授权查询",
},
{
path: "/pre-auth",
title: "新建预授权",
},
],
},
{
icon: "ssisearch",
path: "/charge-query",
title: "收费查询",
children: [],
},
{
icon: "ssiorder",
path: "verification",
title: "核销管理",
children: [
{
path: "/verification",
title: "EOB管理",
},
{
path: "/verification",
title: "新建EOB数据",
},
{
path: "/verification",
title: "回款管理",
},
{
path: "/verification",
title: "新建回款管理",
},
],
},
{
icon: "ssidata",
path: "info",
title: "信息管理",
children: [
{
path: "/info",
title: "医疗机构信息",
},
{
path: "/info",
title: "保险公司信息",
},
],
},
{
icon: "ssiscan",
path: "/bi",
title: "报销",
children: [],
},
];
import NProgress from "nprogress";
import "nprogress/nprogress.css";
// import store from "@/store/index";
// 路由页面路由首位配置
export default (VueRouter) => {
export default (VueRouter, router) => {
// 解决路由点击重复报错
const VueRouterPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(to) {
......@@ -11,12 +13,14 @@ export default (VueRouter) => {
return VueRouterPush.call(this, to).catch((err) => err);
};
// 页面路由切换时进度条
let router = new VueRouter();
// let router = new VueRouter();
router.beforeEach((to, from, next) => {
console.log(to.path);
NProgress.start();
next();
});
router.afterEach(() => {
console.log("done");
NProgress.done();
});
};
const state = {
token: "",
userInfo: {},
menuStack: [],
};
const actions = {
setMenuStack({ state }, data) {
console.log(data);
state.menuStack = data;
},
};
const actions = {};
const mutations = {
// 设置token
setToken(state, token) {
......
<template>
<div class="header">
<div class="logo">商保管理系统</div>
<div class="user-info">
<p class="name">
<Icon :name="'ssiuser'" :size="16" />{{ userInfo.name }}
</p>
<a-dropdown
class="avator"
:getPopupContainer="getPopupContainer"
placement="bottomRight"
>
<div @click="(e) => e.preventDefault()">
<img v-if="userInfo.avator" :src="userInfo.avator" alt="avator" />
<Icon v-else :name="'ssiuser'" :size="32" />
</div>
<a-menu slot="overlay">
<a-menu-item key="1"> 退出登录 </a-menu-item>
</a-menu>
</a-dropdown>
</div>
</div>
</template>
<script>
export default {
data() {
return {
userInfo: {
name: "Holo",
avator: "",
},
};
},
methods: {
getPopupContainer() {
return document.querySelector(".avator");
},
},
};
</script>
<style lang="less" scoped>
.header {
position: fixed;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
color: #252631;
background-color: #fff;
border-bottom: 1px solid #eef1f3;
z-index: 1;
.logo {
.w(323);
.fs(24);
.pa(27, 44, 24, 44);
.lh(33);
font-weight: bold;
border-right: 2px solid #eef1f3;
}
.user-info {
.fs(19);
display: flex;
align-items: center;
color: #778ca2;
.name .icon-class {
.mg-r(12);
}
.avator {
.w-n(32);
.h-n(32);
.mg-f(0, 24, 0, 24);
border-radius: 50%;
img {
width: 100%;
}
}
}
}
</style>
function SubMenu(h, menu, selectMenu) {
let icon;
if (menu.icon) {
// 菜单激活的时候图标要变颜色 图标名称要处理好 应该是在默认的基础上加个'_active'
const iconName =
selectMenu.indexOf(menu.path) < 0 ? menu.icon : menu.icon + "_active";
icon = <Icon name={iconName} size={24} />;
}
return (
<a-sub-menu key={menu.path}>
<span slot="title" class="submenu-title-wrapper">
{icon}
{menu.title}
</span>
{menu.children.map((item) => {
return createMenu.call(this, h, item);
})}
</a-sub-menu>
);
}
function MenuItem(h, menu, selectMenu) {
let icon;
if (menu.icon) {
// 菜单激活的时候图标要变颜色 图标名称要处理好 应该是在默认的基础上加个'_active'
const iconName =
selectMenu.indexOf(menu.path) < 0 ? menu.icon : menu.icon + "_active";
icon = <Icon name={iconName} size={24} />;
}
return (
<a-menu-item key={menu.path}>
<router-link to={menu.path}>
{icon}
{menu.title}
</router-link>
</a-menu-item>
);
}
export default function createMenu(h, menu, selectMenu) {
if (menu.hidden) {
return false;
}
if (menu.children && menu.children.length) {
return SubMenu.call(this, h, menu, selectMenu);
}
return MenuItem.call(this, h, menu, selectMenu);
}
import menuData from "@/router/modules/menu";
import { mapState } from "vuex";
import createMenu from "./components/menuItem";
export default {
data() {
return {
selectData: [],
openKeys: [],
};
},
computed: {
...mapState({
menuStack: (state) => state.common.menuStack,
}),
// 访问下级页的时候记录当前根菜单高亮
currentSelectKey: function () {
const path = this.$route.path;
const dfs = (data) => {
for (let i = 0; i < data.length; i++) {
const item = data[i];
if (item.children && item.children.length) {
const a = dfs(item.children);
if (a) {
this.openKeys = [item.path];
break;
}
} else if (item.path && path.indexOf(item.path) > -1) {
return true;
}
}
};
dfs(menuData);
return [path];
},
},
mounted() {
const path = this.$route.path;
this.menuClick({ key: path });
},
methods: {
subMenuClick(openKeys) {
this.openKeys = openKeys.splice(-1, 1);
},
menuClick({ key }) {
let menuStack = this.menuStack;
let isHere = false;
for (let i = 0; i < this.menuStack.length; i++) {
if (menuStack[i].path === key) {
isHere = true;
}
}
if (!isHere) {
const dfs = (data) => {
for (let i = 0; i < data.length; i++) {
const item = data[i];
if (item.children && item.children.length) {
const a = dfs(item.children);
if (a) {
break;
}
} else if (item.path && item.path === key) {
menuStack.push(item);
this.$store.dispatch("common/setMenuStack", menuStack);
return true;
}
}
};
dfs(menuData);
}
},
},
render(h) {
const selectMenu = [...this.currentSelectKey, ...this.openKeys];
return (
<div class="menu">
<a-menu
mode="inline"
openKeys={this.openKeys}
defaultSelectedKeys={this.currentSelectKey}
onopenChange={this.subMenuClick}
onclick={this.menuClick}
selectedKeys={this.currentSelectKey}
>
{menuData.map((item) => {
return createMenu.call(this, h, item, selectMenu);
})}
</a-menu>
</div>
);
},
};
<template>
<div class="sub-menu">
<router-link
tag="button"
:class="{ btn: true, 'btn-active': isVisit(item.path) }"
v-for="(item, index) in menuStack"
:key="item.path"
:to="item.path"
>
{{ item.title }}
<Icon
@click="closeMenu(index)"
:name="isVisit(item.path) ? 'ssiclose_active' : 'ssiclose'"
:size="22"
/>
</router-link>
<slot name="tips" />
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
computed: {
...mapState({
menuStack: (state) => state.common.menuStack,
}),
},
methods: {
isVisit(val) {
const path = this.$route.path;
return path.indexOf(val) > -1;
},
closeMenu(index) {
const menuStack = JSON.parse(JSON.stringify(this.menuStack));
const isVisit = this.isVisit(menuStack[index].path);
menuStack.splice(index, 1);
this.$store.dispatch("common/setMenuStack", menuStack);
if (isVisit) {
// 关闭的是当前正在查看的
const i = Math.max(0, index - 1);
this.$router.push(menuStack[i].path || "/");
}
},
},
};
</script>
<style lang="less" scoped>
.sub-menu {
.mg-b(21);
.btn {
.fs(19);
.lh(27);
.pa(11, 13, 11, 13);
.mg-r(40);
color: #252631;
border: none;
background-color: #fff;
border-radius: 5px;
cursor: pointer;
}
.btn-active {
color: #fff;
background-color: #2b63ff;
}
}
</style>
<template>
<div>
<div class="menu-layout">
<Header></Header>
<div class="container">
<Menu></Menu>
<div class="content">
<SubMenu></SubMenu>
<router-view />
</div>
</div>
</div>
</template>
<script>
import Header from "./components/Header.vue";
import Menu from "./components/menu";
import SubMenu from "./components/menu/subMenu.vue";
export default {
components: {},
components: {
Header,
Menu,
SubMenu,
},
data() {
return {};
},
......@@ -17,4 +32,75 @@ export default {
};
</script>
<style lang="less" scoped></style>
<style lang="less" scoped>
.menu-layout {
background-color: #f8fafb;
.container {
display: flex;
position: relative;
.pt(92);
// min-height: calc(100vh - 50px);
.content {
flex: 1;
.mg-l(323);
.pa(19, 40, 0, 40);
min-height: calc(100vh - 85px);
}
}
.menu {
position: fixed;
.w(323);
height: calc(100vh - 85px);
overflow: auto;
background-color: #fff;
}
}
</style>
<style lang="less">
// 菜单默认样式及激活样式重置
.menu {
.icon-class {
.mg-r(24);
}
.ant-menu .ant-menu-submenu .ant-menu-submenu-title,
.ant-menu li.ant-menu-item {
.h(85);
.lh(85);
.ant-menu-submenu-arrow {
&::before,
&::after {
content: none;
}
}
}
.ant-menu .ant-menu-submenu .ant-menu-submenu-title,
.ant-menu li.ant-menu-item a {
.fs(19);
color: #778ca2;
}
.ant-menu-sub {
background-color: #f8fafb;
}
.ant-menu-item.ant-menu-item-selected,
.ant-menu-submenu.ant-menu-submenu-open .ant-menu-submenu-title {
background-color: #2b63ff !important;
color: #fff;
&::after {
content: none;
}
a.router-link-active {
color: #fff;
}
}
.ant-menu-sub {
.ant-menu-item.ant-menu-item-selected {
background-color: #fff !important;
a.router-link-active {
color: #2b63ff;
}
}
}
}
</style>
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment