新增加TopNav导航

This commit is contained in:
不做码农 2021-11-06 12:51:43 +08:00
parent 19665ba3f7
commit 78968e029a
10 changed files with 172 additions and 75 deletions

View File

@ -153,25 +153,27 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
.el-menu--horizontal > .el-menu-item { .topmenu-container.el-menu--horizontal > .el-menu-item {
float: left; float: left;
height: 50px; height: 50px !important;
line-height: 50px; line-height: 50px !important;
margin: 0; color: #999093 !important;
border-bottom: 3px solid transparent; padding: 0 5px !important;
color: #999093; margin: 0 10px !important;
padding: 0 5px;
margin: 0 10px;
} }
.el-menu--horizontal > .el-menu-item.is-active { .topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 3px solid #{"var(--theme)"}; border-bottom: 2px solid #{'var(--theme)'} !important;
color: #303133; color: #303133;
} }
/* submenu item */ /* submenu item */
.el-menu--horizontal > .el-submenu .el-submenu__title { .topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
float: left;
height: 50px !important; height: 50px !important;
line-height: 50px !important; line-height: 50px !important;
color: #999093 !important;
padding: 0 5px !important;
margin: 0 10px !important;
} }
</style> </style>

View File

@ -4,8 +4,8 @@
<hamburger id="hamburger-container" class="hamburger-container" :is-active="sidebar.opened" @toggleClick="toggleSideBar" /> <hamburger id="hamburger-container" class="hamburger-container" :is-active="sidebar.opened" @toggleClick="toggleSideBar" />
<!-- 面包屑导航 --> <!-- 面包屑导航 -->
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" /> <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
<!-- <top-nav id="topmenu-container" class="topmenu-container" v-if="!topNav"/> --> <top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
<div class="right-menu"> <div class="right-menu">
<template v-if="device!=='mobile'"> <template v-if="device!=='mobile'">
@ -46,6 +46,7 @@
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import Breadcrumb from "@/components/Breadcrumb"; import Breadcrumb from "@/components/Breadcrumb";
import TopNav from '@/components/TopNav'
import Hamburger from "@/components/Hamburger"; import Hamburger from "@/components/Hamburger";
import Screenfull from "@/components/Screenfull"; import Screenfull from "@/components/Screenfull";
import SizeSelect from "@/components/SizeSelect"; import SizeSelect from "@/components/SizeSelect";
@ -56,6 +57,7 @@ import ZrDoc from '@/components/Zr/Doc'
export default { export default {
components: { components: {
Breadcrumb, Breadcrumb,
TopNav,
Hamburger, Hamburger,
Screenfull, Screenfull,
SizeSelect, SizeSelect,
@ -76,6 +78,11 @@ export default {
}); });
}, },
}, },
topNav: {
get() {
return this.$store.state.settings.topNav
}
}
}, },
methods: { methods: {
toggleSideBar() { toggleSideBar() {
@ -128,6 +135,11 @@ export default {
float: left; float: left;
} }
.topmenu-container {
position: absolute;
left: 50px;
}
.errLog-container { .errLog-container {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;

View File

@ -33,6 +33,14 @@
</div> </div>
<el-divider /> <el-divider />
<h3 class="drawer-title">系统布局配置</h3>
<div class="drawer-item">
<span>开启 TopNav</span>
<el-switch v-model="topNav" class="drawer-switch" />
</div>
<div class="drawer-item"> <div class="drawer-item">
<span>开启 Tags-Views</span> <span>开启 Tags-Views</span>
<el-switch v-model="tagsView" class="drawer-switch" /> <el-switch v-model="tagsView" class="drawer-switch" />
@ -78,6 +86,20 @@ export default {
}); });
}, },
}, },
topNav: {
get() {
return this.$store.state.settings.topNav
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'topNav',
value: val
})
if (!val) {
this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes);
}
}
},
tagsView: { tagsView: {
get() { get() {
return this.$store.state.settings.tagsView; return this.$store.state.settings.tagsView;
@ -128,6 +150,7 @@ export default {
localStorage.setItem( localStorage.setItem(
"layout-setting", "layout-setting",
`{ `{
"topNav":${this.topNav},
"tagsView":${this.tagsView}, "tagsView":${this.tagsView},
"fixedHeader":${this.fixedHeader}, "fixedHeader":${this.fixedHeader},
"sidebarLogo":${this.sidebarLogo}, "sidebarLogo":${this.sidebarLogo},

View File

@ -2,9 +2,11 @@
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }"> <div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<logo v-if="showLogo" :collapse="isCollapse" /> <logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper"> <el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor" :unique-opened="true" :active-text-color="settings.theme" :collapse-transition="false" mode="vertical"> <el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground" :text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor" :unique-opened="true"
<sidebar-item v-for="(route, index) in permission_routes" :key="route.path + index" :item="route" :base-path="route.path" /> :active-text-color="settings.theme" :collapse-transition="false" mode="vertical">
<sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" />
</el-menu> </el-menu>
</el-scrollbar> </el-scrollbar>
</div> </div>
@ -20,7 +22,7 @@ export default {
components: { SidebarItem, Logo }, components: { SidebarItem, Logo },
computed: { computed: {
...mapState(["settings"]), ...mapState(["settings"]),
...mapGetters(["permission_routes", "sidebar"]), ...mapGetters(["sidebarRouters", "sidebar"]),
activeMenu() { activeMenu() {
const route = this.$route; const route = this.$route;
const { meta, path } = route; const { meta, path } = route;

View File

@ -14,6 +14,11 @@ module.exports = {
*/ */
showSettings: false, showSettings: false,
/**
* 是否显示顶部导航
*/
topNav: false,
/** /**
* 是否显示 tagsView * 是否显示 tagsView
*/ */

View File

@ -12,5 +12,8 @@ const getters = {
permissions: state => state.user.permissions, permissions: state => state.user.permissions,
permission_routes: state => state.permission.routes, permission_routes: state => state.permission.routes,
userinfo: state => state.user.userInfo, userinfo: state => state.user.userInfo,
topbarRouters: state => state.permission.topbarRouters,
defaultRoutes: state => state.permission.defaultRoutes,
sidebarRouters: state => state.permission.sidebarRouters,
} }
export default getters export default getters

View File

@ -6,13 +6,30 @@ import ParentView from '@/components/ParentView';
const permission = { const permission = {
state: { state: {
routes: [], routes: [],
addRoutes: [] addRoutes: [],
defaultRoutes: [],
topbarRouters: [],
sidebarRouters: []
}, },
mutations: { mutations: {
SET_ROUTES: (state, routes) => { SET_ROUTES: (state, routes) => {
state.addRoutes = routes state.addRoutes = routes
state.routes = constantRoutes.concat(routes) state.routes = constantRoutes.concat(routes)
} },
SET_DEFAULT_ROUTES: (state, routes) => {
state.defaultRoutes = constantRoutes.concat(routes)
},
SET_TOPBAR_ROUTES: (state, routes) => {
// 顶部导航菜单默认添加统计报表栏指向首页
const index = [{
path: 'index',
meta: { title: '统计报表', icon: 'dashboard' }
}]
state.topbarRouters = routes; //.concat(index);
},
SET_SIDEBAR_ROUTERS: (state, routes) => {
state.sidebarRouters = routes
},
}, },
actions: { actions: {
// 生成路由 // 生成路由
@ -20,10 +37,16 @@ const permission = {
return new Promise(resolve => { return new Promise(resolve => {
// 向后端请求路由数据 // 向后端请求路由数据
getRouters().then(res => { getRouters().then(res => {
const accessedRoutes = filterAsyncRouter(res.data) const sdata = JSON.parse(JSON.stringify(res.data))
// accessedRoutes.push({ path: '*', redirect: '/404', hidden: true }) const rdata = JSON.parse(JSON.stringify(res.data))
commit('SET_ROUTES', accessedRoutes) const sidebarRoutes = filterAsyncRouter(sdata)
resolve(accessedRoutes) const rewriteRoutes = filterAsyncRouter(rdata, false, true)
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
commit('SET_ROUTES', rewriteRoutes)
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
commit('SET_TOPBAR_ROUTES', sidebarRoutes)
resolve(rewriteRoutes)
}) })
}) })
} }
@ -31,9 +54,11 @@ const permission = {
} }
// 遍历后台传来的路由字符串,转换为组件对象 // 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap) { function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
return asyncRouterMap.filter(route => { return asyncRouterMap.filter(route => {
// console.log(JSON.stringify(route)) if (type && route.children) {
route.children = filterChildren(route.children)
}
if (route.component) { if (route.component) {
// Layout ParentView 组件特殊处理 // Layout ParentView 组件特殊处理
if (route.component === 'Layout') { if (route.component === 'Layout') {
@ -45,12 +70,39 @@ function filterAsyncRouter(asyncRouterMap) {
} }
} }
if (route.children != null && route.children && route.children.length) { if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children) route.children = filterAsyncRouter(route.children, route, type)
} else {
delete route['children']
delete route['redirect']
} }
return true return true
}) })
} }
function filterChildren(childrenMap, lastRouter = false) {
var children = []
childrenMap.forEach((el, index) => {
if (el.children && el.children.length) {
if (el.component === 'ParentView') {
el.children.forEach(c => {
c.path = el.path + '/' + c.path
if (c.children && c.children.length) {
children = children.concat(filterChildren(c.children, c))
return
}
children.push(c)
})
return
}
}
if (lastRouter) {
el.path = lastRouter.path + '/' + el.path
}
children = children.concat(el)
})
return children
}
export const loadView = (view) => { // 路由懒加载 export const loadView = (view) => { // 路由懒加载
return (resolve) => require([`@/views/${view}`], resolve) return (resolve) => require([`@/views/${view}`], resolve)
} }

View File

@ -1,16 +1,16 @@
import defaultSettings from '@/settings' import defaultSettings from '@/settings'
const { theme, sideTheme, showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings const { theme, sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const state = { const state = {
theme: storageSetting.theme || theme, //主题颜色 theme: storageSetting.theme || theme, //主题颜色
sideTheme: storageSetting.sideTheme || sideTheme, //侧边主题样式 sideTheme: storageSetting.sideTheme || sideTheme, //侧边主题样式
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
showSettings: showSettings, showSettings: showSettings,
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
// topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
// dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle // dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
} }
@ -35,4 +35,3 @@ export default {
mutations, mutations,
actions actions
} }

View File

@ -39,7 +39,7 @@
import { getCodeImg } from "@/api/system/login"; import { getCodeImg } from "@/api/system/login";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt"; import { encrypt, decrypt } from "@/utils/jsencrypt";
import defaultSettings from '@/settings' import defaultSettings from "@/settings";
export default { export default {
name: "Login", name: "Login",
@ -98,8 +98,7 @@ export default {
this.loginForm = { this.loginForm = {
username: username === undefined ? this.loginForm.username : username, username: username === undefined ? this.loginForm.username : username,
password: password: password === undefined ? this.loginForm.password : password,
password === undefined ? this.loginForm.password : password,
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe), rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
}; };
}, },
@ -152,7 +151,7 @@ export default {
height: 100%; height: 100%;
// background-image: url("../assets/image/login-background.jpg"); // background-image: url("../assets/image/login-background.jpg");
background-size: cover; background-size: cover;
background-color: rgba(56,157,170,.82); background-color: rgba(56, 157, 170, 0.82);
} }
.title { .title {
margin: 0px auto 30px auto; margin: 0px auto 30px auto;
@ -164,7 +163,7 @@ export default {
.login-form { .login-form {
border-radius: 6px; border-radius: 6px;
// background: #ffffff; // background: #ffffff;
background-color: hsla(0,0%,100%,.3); background-color: hsla(0, 0%, 100%, 0.3);
width: 350px; width: 350px;
padding: 25px 25px 5px 25px; padding: 25px 25px 5px 25px;
.el-input { .el-input {