路由主布局代码优化

master
toesbieya 6 years ago
parent dd6f87ed04
commit 163e803939
  1. 4
      vue/src/layout/component/Navbar/component/Bell.vue
  2. 4
      vue/src/layout/component/Navbar/component/Hamburger.vue
  3. 49
      vue/src/layout/component/Navbar/index.vue
  4. 93
      vue/src/layout/component/Sidebar/component/SidebarItem.vue
  5. 73
      vue/src/layout/component/Sidebar/index.vue
  6. 4
      vue/src/layout/component/TagsView/ScrollPane.vue
  7. 14
      vue/src/layout/component/TagsView/index.vue
  8. 0
      vue/src/layout/component/TagsView/mixin/shortcut.js

@ -1,6 +1,6 @@
<template>
<el-badge :hidden="hidden" class="bell-badge" is-dot @click.native="jump">
<i class="el-icon-bell navbar-icon" title="消息提醒"/>
<el-badge :hidden="hidden" class="bell-badge" is-dot title="消息提醒" @click.native="jump">
<i class="el-icon-bell navbar-icon"/>
</el-badge>
</template>

@ -8,9 +8,9 @@ export default {
render(h, context) {
const {active} = context.props
const className = {'navbar-icon': true, 'el-icon-s-unfold': true, 'hamburger': true, 'is-active': active}
const className = `navbar-icon el-icon-s-unfold hamburger ${active ? 'is-active' : ''}`
return (
<div {...context.data}>
<div {...context.data} title={`${active ? '折叠' : '展开'}侧边栏`}>
<i class={className}/>
</div>
)

@ -3,37 +3,38 @@
<div>
<hamburger class="navbar-item" :active="!sidebarCollapse" @click="sidebarCtrl"/>
<div class="navbar-item" @click="refresh">
<i class="el-icon-refresh-right navbar-icon" title="刷新"/>
</div>
<breadcrumb v-if="showBreadcrumb"/>
</div>
<div>
<bell class="navbar-item"/>
<div class="setting-btn navbar-item hidden-xs" @click="settingDrawer=true">
<i class="el-icon-s-operation navbar-icon" title="个性设置"/>
<div class="navbar-item" title="刷新" @click="refresh">
<i class="el-icon-refresh-right navbar-icon"/>
</div>
<div class="setting-btn navbar-item hidden-xs" title="个性设置" @click="settingDrawer = true">
<i class="el-icon-s-operation navbar-icon"/>
</div>
<el-dropdown
class="navbar-item"
trigger="click"
@visible-change="$emit('menu-show',$event)"
@command="command"
@visible-change="e => $emit('menu-show',e)"
>
<div class="avatar-wrapper">
<el-avatar :size="30" :src="avatar" icon="el-icon-user-solid"/>
<span class="hidden-xs">{{ name }}</span>
</div>
<el-dropdown-menu class="user-dropdown" slot="dropdown">
<router-link to="/user">
<el-dropdown-item icon="el-icon-user">个人中心</el-dropdown-item>
</router-link>
<el-dropdown-item class="hidden-xs" icon="el-icon-guide" @click.native="()=>$guide(0,guideSteps)">
<el-dropdown-item icon="el-icon-user" command="user">
个人中心
</el-dropdown-item>
<el-dropdown-item class="hidden-xs" icon="el-icon-guide" command="guide">
新手指引
</el-dropdown-item>
<el-dropdown-item divided icon="el-icon-switch-button" @click.native="logout">
<el-dropdown-item divided icon="el-icon-switch-button" command="logout">
退出登录
</el-dropdown-item>
</el-dropdown-menu>
@ -61,11 +62,7 @@ export default {
components: {Hamburger, Breadcrumb, Bell, SettingDrawer},
data() {
return {
settingDrawer: false
}
},
data: () => ({settingDrawer: false}),
computed: {
...mapState('user', ['avatar', 'name', 'prepareLogout']),
@ -77,15 +74,23 @@ export default {
sidebarCtrl() {
this.$store.commit('setting/sidebarCollapse', !this.sidebarCollapse)
},
refresh() {
this.$router.replace({path: `/redirect${this.$route.fullPath}`})
},
logout() {
if (this.prepareLogout) return
elConfirm('确认退出?')
.then(() => this.$store.dispatch('user/logout'))
command(command) {
switch (command) {
case 'user':
this.$router.push('/user')
break
case 'guide':
this.$guide(0, this.guideSteps)
break
case 'logout':
if (this.prepareLogout) return
elConfirm('确认退出?').then(() => this.$store.dispatch('user/logout'))
break
}
}
}
}

@ -1,72 +1,83 @@
<script type="text/jsx">
import SidebarItemContent from './SidebarItemContent'
function getOnlyChild(item) {
const {children = [], meta: {alwaysShow} = {}} = item
//
function getOnlyChild(menu) {
const {children = [], meta: {alwaysShow} = {}} = menu
if (children.length === 1) return alwaysShow ? null : children[0]
if (!children.length) return {...menu, children: undefined}
if (!children.length) return {...item, path: undefined, children: undefined}
if (children.length === 1) return alwaysShow ? null : getOnlyChild(children[0])
return null
}
function renderNode(h, {item, showParent, collapse}) {
let onlyOneChild = getOnlyChild(item)
function renderSingleMenu(h, {index, icon, title}) {
return (
<el-menu-item index={index}>
<SidebarItemContent icon={icon} title={title}/>
</el-menu-item>
)
}
function renderSubMenu(h, {index, icon, title, children}) {
return (
<el-submenu index={index} popper-append-to-body>
<SidebarItemContent slot="title" icon={icon} title={title}/>
{children}
</el-submenu>
)
}
function renderChildrenWithParentMenu(h, {icon, title, children}) {
return [
<div class="popover-menu__title el-menu-item">
<SidebarItemContent icon={icon} title={title}/>
</div>,
<div class="el-menu el-menu--inline">{children}</div>
]
}
function renderMenu(h, {menu, showParent, collapse}) {
const onlyOneChild = getOnlyChild(menu)
const showSingle = onlyOneChild && !onlyOneChild.children
if (showSingle) {
const {icon, title} = onlyOneChild.meta
return (
<el-menu-item index={onlyOneChild.fullPath}>
<SidebarItemContent icon={icon} title={title}/>
</el-menu-item>
)
return renderSingleMenu(h, {index: onlyOneChild.fullPath, icon, title})
}
else {
const {icon, title} = item.meta
let children = item.children.map(child => renderNode(h, {
item: child,
showParent,
collapse
}))
//mouseleavemouseleave
if (collapse) {
//
if (showParent) {
children = [
<div class="popover-menu__title el-menu-item">
<SidebarItemContent icon={icon} title={title}/>
</div>,
<div class="el-menu el-menu--inline">{children}</div>
]
}
}
return (
<el-submenu index={item.fullPath} popper-append-to-body>
<SidebarItemContent slot="title" icon={icon} title={title}/>
{children}
</el-submenu>
)
const {icon, title} = menu.meta
let children = menu.children.map(child => renderMenu(h, {
menu: child,
showParent,
collapse
}))
//<el-scrollbar>mouseleavemouseleave
if (collapse) {
//
if (showParent) {
children = renderChildrenWithParentMenu(h, {icon, title, children})
}
}
return renderSubMenu(h, {index: menu.fullPath, icon, title, children})
}
export default {
functional: true,
props: {
item: Object,
menu: Object,
showParent: Boolean,
collapse: Boolean
},
render(h, context) {
return renderNode(h, context.props)
return renderMenu(h, context.props)
}
}
</script>

@ -9,11 +9,7 @@ export default {
components: {SidebarItem, Logo},
data() {
return {
mouseOutside: true
}
},
data: () => ({mouseOutside: true, activeMenu: ''}),
computed: {
...mapState('app', ['device']),
@ -22,20 +18,14 @@ export default {
...mapState('setting', ['showLogo', 'sidebarCollapse', 'sidebarUniqueOpen', 'sidebarShowParent', 'sidebarAutoHidden']),
activeMenu() {
const route = this.$route
const {meta, path} = route
if (path.startsWith('/redirect')) {
return path.replace('/redirect', '')
}
return meta.activeMenu || path
},
//pc
collapse() {
return this.sidebarCollapse && this.device === 'pc'
},
//
//
//
hideSidebar() {
return this.sidebarAutoHidden && this.mouseOutside
|| this.sidebarCollapse && this.device === 'mobile'
@ -53,19 +43,33 @@ export default {
watch: {
//elMenuinitOpenedMenu()select
'$route.path'(nv, ov) {
//redirect
if (nv === `/redirect${ov}`) return
const menu = this.$refs.menu
if (!menu) return
const item = menu.items[this.activeMenu]
if (!item) menu.openedMenus = []
else this.select(item.index, item.indexPath, item, false)
'$route.path': {
immediate: true,
handler(v) {
//redirect
if (v.startsWith('/redirect')) return
this.setActiveMenu()
const menu = this.$refs.menu
if (!menu) return
const item = menu.items[this.activeMenu]
//
if (!item) return menu.openedMenus = []
this.select(item.index, item.indexPath, item, false)
}
},
hideSidebar(v) {
if (v) document.addEventListener('mousemove', this.moveEvent)
else document.removeEventListener('mousemove', this.moveEvent)
//
hideSidebar: {
immediate: true,
handler(v) {
if (!this.sidebarAutoHidden) return
const key = `${v ? 'add' : 'remove'}EventListener`
document[key]('mousemove', this.moveEvent)
}
}
},
@ -74,6 +78,13 @@ export default {
if (e.clientX <= 15) this.mouseOutside = false
},
//
setActiveMenu() {
const {meta, path} = this.$route
this.activeMenu = meta.activeMenu || path
},
//
select(index, indexPath, item, jump = true) {
//
if (this.sidebarUniqueOpen && indexPath.length === 1) {
@ -100,14 +111,8 @@ export default {
}
},
mounted() {
if (this.sidebarAutoHidden) {
document.addEventListener('mousemove', this.moveEvent)
}
this.$once('hook:beforeDestroy', () => {
document.removeEventListener('mousemove', this.moveEvent)
})
beforeDestroy() {
document.removeEventListener('mousemove', this.moveEvent)
},
render() {
@ -126,7 +131,7 @@ export default {
key={menu.path}
show-parent={this.sidebarShowParent}
collapse={this.sidebarCollapse}
item={menu}
menu={menu}
/>
))}
</el-menu>

@ -1,5 +1,5 @@
<template>
<el-scrollbar ref="scrollContainer" native @wheel.native.prevent="handleScroll">
<el-scrollbar ref="scrollContainer" native noresize @wheel.native.prevent="handleScroll">
<slot/>
</el-scrollbar>
</template>
@ -10,8 +10,6 @@ const tagAndTagSpacing = 4
export default {
name: 'ScrollPane',
data: () => ({rAF: null}),
methods: {
getWrapper() {
return this.$refs.scrollContainer.$refs.wrap

@ -8,8 +8,8 @@
:class="{'tags-view-item': true, active: isActive(tag)}"
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
tag="div"
@contextmenu.prevent.native="e => openMenu(tag, e)"
@dblclick.prevent.native="() => closeSelectedTag(tag)"
@contextmenu.prevent.stop.native="e => openMenu(tag, e)"
@dblclick.prevent.stop.native="() => closeSelectedTag(tag)"
>
{{ tag.title }}
<i v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="() => closeSelectedTag(tag)"/>
@ -27,15 +27,15 @@
</nav>
</template>
<script>
import ScrollPane from './ScrollPane'
<script type="text/jsx">
import shortcutMixin from './mixin/shortcut'
import decideRouterTransitionMixin from './mixin/decideRouterTransition'
import ContextMenu from "@/component/ContextMenu"
import ContextMenuItem from "@/component/ContextMenu/item"
import shortcuts from './mixin/shortcuts'
import decideRouterTransition from './mixin/decideRouterTransition'
import ScrollPane from './ScrollPane'
export default {
mixins: [shortcuts, decideRouterTransition],
mixins: [shortcutMixin, decideRouterTransitionMixin],
components: {ContextMenu, ContextMenuItem, ScrollPane},

Loading…
Cancel
Save