Skip to content

Commit

Permalink
feat(admin): add basic page-tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
Aysnine committed Dec 30, 2019
1 parent ffee280 commit 1d92e0d
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 14 deletions.
7 changes: 7 additions & 0 deletions src/views/admin/$index/components/PageContainer/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,11 @@ export default {
border-radius $top-radius
&.no-body-padding > .center-wapper > .body
padding 0
// for <PageTabs />
&.sharp-top
&.sharp-top > .header
border-top none
border-top-left-radius 0
border-top-right-radius 0
</style>
114 changes: 114 additions & 0 deletions src/views/admin/$index/components/PageTabs/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<template>
<el-tabs
:value="current"
type="card"
class="tabs"
@tab-remove="onClose"
@tab-click="onClick"
>
<el-tab-pane
v-for="(item, index) in opened"
:key="item.index"
:label="item.label"
:name="item.index"
:closable="item.closeable || !!index"
/>
</el-tabs>
</template>

<script>
import { find, uniqBy } from 'lodash'
export default {
name: 'PageTabs',
props: {
current: {
// recommend $route.path
type: String,
required: true
},
opened: {
type: Array,
required: true
},
options: {
type: Array,
required: true
}
},
watch: {
current: {
immediate: true,
handler(index) {
const optional = find(this.options, { index })
if (optional) {
const opened = find(this.opened, { index })
if (!opened) {
this.$emit('update:opened', [...this.opened, optional])
}
} else {
// eslint-disable-next-line no-console
console.warn('not found index', index)
}
}
}
},
methods: {
onClose(targetIndex) {
let tabs = this.opened
let current = this.current
if (current === targetIndex) {
tabs.forEach((tab, index) => {
if (tab.index === targetIndex) {
let nextTab = tabs[index + 1] || tabs[index - 1]
if (nextTab) {
current = nextTab.index
}
}
})
}
if (this.current !== current) {
this.$emit('switch', find(this.opened, { index: current }))
}
this.$emit(
'update:opened',
tabs.filter(tab => tab.index !== targetIndex)
)
},
onClick(tab) {
if (tab.name !== this.current) {
this.$emit('switch', find(this.opened, { index: tab.name }))
}
}
}
}
</script>

<style lang="stylus" scoped>
@import '../../../../../style/variable.styl'
.tabs
color $regular-text-color
>
>>>
.el-tabs__header
margin 0
border-color $border-base-color
.el-tabs__nav
overflow hidden
.el-tabs__nav
.el-tabs__item
color inherit
border-color $border-base-color
background $background-solid-color
.el-tabs__item
&.is-active
color $foreground-color
border-bottom none
background $background-white-color
&:not(.is-active)
&:hover, &:active
color inherit
.el-tabs__content
display none
</style>
54 changes: 40 additions & 14 deletions src/views/admin/$index/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,61 @@
<el-aside class="aside" width="auto">
<aside-nav-menu :menu="menu" :collapse="isCollapse" />
</el-aside>
<el-main class="main">
<transition :name="transition">
<div class="transition-wrapper" :key="$route.path">
<router-view />
</div>
</transition>
</el-main>
<el-container>
<el-header class="tabs-wrapper" height="auto" v-if="hasTabs">
<page-tabs
:current="$route.path"
v-bind.sync="tabsData"
@switch="handleSwitchTabs"
/>
</el-header>
<el-main class="main">
<transition :name="pageTransition">
<div class="page-wrapper" :key="$route.path">
<router-view :class="{ 'sharp-top': hasTabs }" />
</div>
</transition>
</el-main>
</el-container>
</el-container>
</el-container>
</template>

<script>
import { filter, uniqBy } from 'lodash'
import AsideNavMenu from './components/AsideNavMenu'
import AsideNavMenuToggle from './components/AsideNavMenuToggle'
import PageTabs from './components/PageTabs'
import menu from './menu'
import { flattenMenuItemOfAdmin } from './utils'
export default {
data() {
const tabOptions = flattenMenuItemOfAdmin(menu)
const tabOpened = [tabOptions[0]]
return {
isCollapse: false,
menu,
transition: 'fade-transverse'
hasTabs: true,
tabsData: {
opened: tabOpened,
options: tabOptions
},
isCollapse: false,
pageTransition: 'fade-transverse' // '[name]' | ''
}
},
methods: {
switchCollapse() {
this.isCollapse = !this.isCollapse
handleSwitchTabs({ index }) {
this.$router.push(index)
}
},
components: {
AsideNavMenu,
AsideNavMenuToggle
AsideNavMenuToggle,
PageTabs
}
}
</script>
Expand All @@ -64,10 +87,13 @@ $right-margin = 20px
.aside
>>> .el-menu-vertical:not(.el-menu--collapse)
width $aside-width
.tabs-wrapper
padding 0
margin-right $right-margin
.main
position relative
padding 0
.transition-wrapper
.page-wrapper
position absolute
top 0
left 0
Expand All @@ -79,7 +105,7 @@ $right-margin = 20px
&-leave-active
&-enter-active
transition-property opacity transform
transition-duration .45s
transition-duration .3s
transition-timing-function ease-out
&-enter
opacity 0
Expand Down
19 changes: 19 additions & 0 deletions src/views/admin/$index/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { map, flattenDeep, uniqBy, filter } from 'lodash'

const flattenMenuItem = (() => {
const it = collection =>
map(collection, item => {
const { children, group } = item
if (children) return it(children)
if (group) return it(group)
return item
})

return treeMenuData => flattenDeep(it(treeMenuData))
})()

export const flattenMenuItemOfAdmin = menu =>
uniqBy(
filter(flattenMenuItem(menu), ({ index }) => /^\/admin/.test(index)),
'index'
)

0 comments on commit 1d92e0d

Please sign in to comment.