新增加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>
<style lang="scss">
.el-menu--horizontal > .el-menu-item {
.topmenu-container.el-menu--horizontal > .el-menu-item {
float: left;
height: 50px;
line-height: 50px;
margin: 0;
border-bottom: 3px solid transparent;
color: #999093;
padding: 0 5px;
margin: 0 10px;
height: 50px !important;
line-height: 50px !important;
color: #999093 !important;
padding: 0 5px !important;
margin: 0 10px !important;
}
.el-menu--horizontal > .el-menu-item.is-active {
border-bottom: 3px solid #{"var(--theme)"};
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 2px solid #{'var(--theme)'} !important;
color: #303133;
}
/* 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;
line-height: 50px !important;
color: #999093 !important;
padding: 0 5px !important;
margin: 0 10px !important;
}
</style>

View File

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

View File

@ -33,6 +33,14 @@
</div>
<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">
<span>开启 Tags-Views</span>
<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: {
get() {
return this.$store.state.settings.tagsView;
@ -128,6 +150,7 @@ export default {
localStorage.setItem(
"layout-setting",
`{
"topNav":${this.topNav},
"tagsView":${this.tagsView},
"fixedHeader":${this.fixedHeader},
"sidebarLogo":${this.sidebarLogo},

View File

@ -2,9 +2,11 @@
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<logo v-if="showLogo" :collapse="isCollapse" />
<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">
<sidebar-item v-for="(route, index) in permission_routes" :key="route.path + index" :item="route" :base-path="route.path" />
<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">
<sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
@ -20,7 +22,7 @@ export default {
components: { SidebarItem, Logo },
computed: {
...mapState(["settings"]),
...mapGetters(["permission_routes", "sidebar"]),
...mapGetters(["sidebarRouters", "sidebar"]),
activeMenu() {
const route = this.$route;
const { meta, path } = route;

View File

@ -37,15 +37,15 @@ Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree
Vue.prototype.msgSuccess = function (msg) {
Vue.prototype.msgSuccess = function(msg) {
this.$message({ showClose: true, message: msg, type: "success" });
}
Vue.prototype.msgError = function (msg) {
Vue.prototype.msgError = function(msg) {
this.$message({ showClose: true, message: msg, type: "error" });
}
Vue.prototype.msgInfo = function (msg) {
Vue.prototype.msgInfo = function(msg) {
this.$message.info(msg);
}
@ -76,4 +76,4 @@ new Vue({
router,
store,
render: h => h(App)
})
})

View File

@ -7,13 +7,18 @@ module.exports = {
/**
* 侧边栏主题 深色主题theme-dark浅色主题theme-light
*/
sideTheme: 'theme-light',
sideTheme: 'theme-light',
/**
* 显示是否系统布局配置
*/
showSettings: false,
/**
* 是否显示顶部导航
*/
topNav: false,
/**
* 是否显示 tagsView
*/
@ -36,4 +41,4 @@ module.exports = {
* If you want to also use it in dev, you can pass ['production', 'development']
*/
errorLog: 'production'
}
}

View File

@ -1,16 +1,19 @@
const getters = {
sidebar: state => state.app.sidebar,
size: state => state.app.size,
device: state => state.app.device,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permissions: state => state.user.permissions,
permission_routes: state => state.permission.routes,
userinfo: state => state.user.userInfo,
sidebar: state => state.app.sidebar,
size: state => state.app.size,
device: state => state.app.device,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permissions: state => state.user.permissions,
permission_routes: state => state.permission.routes,
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 = {
state: {
routes: [],
addRoutes: []
addRoutes: [],
defaultRoutes: [],
topbarRouters: [],
sidebarRouters: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = 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: {
// 生成路由
@ -20,10 +37,16 @@ const permission = {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
const accessedRoutes = filterAsyncRouter(res.data)
// accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
const sdata = JSON.parse(JSON.stringify(res.data))
const rdata = JSON.parse(JSON.stringify(res.data))
const sidebarRoutes = filterAsyncRouter(sdata)
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 => {
// console.log(JSON.stringify(route))
if (type && route.children) {
route.children = filterChildren(route.children)
}
if (route.component) {
// Layout ParentView 组件特殊处理
if (route.component === 'Layout') {
@ -45,14 +70,41 @@ function filterAsyncRouter(asyncRouterMap) {
}
}
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
})
}
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) => { // 路由懒加载
return (resolve) => require([`@/views/${view}`], resolve)
}
export default permission
export default permission

View File

@ -1,38 +1,37 @@
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 state = {
theme: storageSetting.theme || theme,//主题颜色
sideTheme: storageSetting.sideTheme || sideTheme,//侧边主题样式
showSettings: showSettings,
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
// topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
// dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
theme: storageSetting.theme || theme, //主题颜色
sideTheme: storageSetting.sideTheme || sideTheme, //侧边主题样式
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
showSettings: showSettings,
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
// dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
}
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
if (state.hasOwnProperty(key)) {
state[key] = value
CHANGE_SETTING: (state, { key, value }) => {
if (state.hasOwnProperty(key)) {
state[key] = value
}
}
}
}
const actions = {
//修改布局设置
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
//修改布局设置
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
namespaced: true,
state,
mutations,
actions
}

View File

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