feat: add function of fixing the head of tabs;

新增:固定页签头功能。
master
chenghongxing 5 years ago
parent 9df2666304
commit 83576d88d7
  1. 1
      src/config/default/setting.config.js
  2. 26
      src/layouts/AdminLayout.vue
  3. 155
      src/layouts/tabs/TabsHead.vue
  4. 25
      src/layouts/tabs/TabsView.vue
  5. 3
      src/store/modules/setting.js

@ -11,6 +11,7 @@ module.exports = {
layout: 'side', //导航布局,可选 side 和 head,分别为侧边导航和顶部导航
fixedHeader: false, //固定头部状态栏,true:固定,false:不固定
fixedSideBar: true, //固定侧边栏,true:固定,false:不固定
fixedTabs: false, //固定页签头,true:固定,false:不固定
pageWidth: 'fixed', //内容区域宽度,fixed:固定宽度,fluid:流式宽度
weekMode: false, //色弱模式,true:开启,false:不开启
multiPage: false, //多页签模式,true:开启,false:不开启

@ -12,8 +12,8 @@
<setting />
</drawer>
<a-layout class="admin-layout-main beauty-scroll">
<admin-header :style="headerStyle" :menuData="headMenuData" :collapsed="collapsed" @toggleCollapse="toggleCollapse"/>
<a-layout-header v-if="fixedHeader"></a-layout-header>
<admin-header :class="[{'fixed-tabs': fixedTabs, 'fixed-header': fixedHeader, 'multi-page': multiPage}]" :style="headerStyle" :menuData="headMenuData" :collapsed="collapsed" @toggleCollapse="toggleCollapse"/>
<a-layout-header :class="['virtual-header', {'fixed-tabs' : fixedTabs, 'fixed-header': fixedHeader, 'multi-page': multiPage}]" v-show="fixedHeader"></a-layout-header>
<a-layout-content class="admin-layout-content">
<div :style="`min-height: ${minHeight}px; position: relative`">
<slot></slot>
@ -47,6 +47,11 @@ export default {
drawerOpen: false
}
},
provide() {
return {
adminLayout: this
}
},
watch: {
$route(val) {
this.setActivated(val)
@ -62,7 +67,7 @@ export default {
},
computed: {
...mapState('setting', ['isMobile', 'theme', 'layout', 'footerLinks', 'copyright', 'fixedHeader', 'fixedSideBar',
'hideSetting']),
'fixedTabs', 'hideSetting', 'multiPage']),
...mapGetters('setting', ['firstMenu', 'subMenu', 'menuData']),
sideMenuWidth() {
return this.collapsed ? '80px' : '256px'
@ -70,8 +75,7 @@ export default {
headerStyle() {
let width = (this.fixedHeader && this.layout !== 'head' && !this.isMobile) ? `calc(100% - ${this.sideMenuWidth})` : '100%'
let position = this.fixedHeader ? 'fixed' : 'static'
let transition = this.fixedHeader ? 'transition: width 0.2s' : ''
return `width: ${width}; position: ${position}; ${transition}`
return `width: ${width}; position: ${position};`
},
headMenuData() {
const {layout, menuData, firstMenu} = this
@ -127,10 +131,22 @@ export default {
.virtual-side{
transition: all 0.2s;
}
.virtual-header{
transition: all 0.2s;
opacity: 0;
&.fixed-tabs.multi-page:not(.fixed-header){
height: 0;
}
}
.admin-layout-main{
.admin-header{
top: 0;
right: 0;
overflow: hidden;
transition: all 0.2s;
&.fixed-tabs.multi-page:not(.fixed-header){
height: 0;
}
}
}
.admin-layout-content{

@ -0,0 +1,155 @@
<template>
<div :class="['tabs-head', layout, pageWidth]">
<a-tabs
type="editable-card"
:class="['tabs-container', layout, pageWidth, {'affixed' : affixed, 'fixed-header' : fixedHeader, 'collapsed' : adminLayout.collapsed}]"
:active-key="active"
:hide-add="true"
@change="onChange"
@edit="onEdit"
@contextmenu="onContextmenu"
>
<a-tooltip placement="left" :title="lockTitle" slot="tabBarExtraContent">
<a-icon
theme="filled"
@click="onLockClick"
class="header-lock"
:type="fixedTabs ? 'lock' : 'unlock'"
/>
</a-tooltip>
<a-tab-pane v-for="page in pageList" :key="page.fullPath">
<span slot="tab" :pagekey="page.fullPath">{{pageName(page)}}</span>
</a-tab-pane>
</a-tabs>
<div v-if="affixed" class="virtual-tabs"></div>
</div>
</template>
<script>
import {mapState, mapMutations} from 'vuex'
import {getI18nKey} from '@/utils/routerUtil'
export default {
name: 'TabsHead',
i18n: {
messages: {
CN: {
lock: '点击锁定页签头',
unlock: '点击解除锁定',
},
HK: {
lock: '點擊鎖定頁簽頭',
unlock: '點擊解除鎖定',
},
US: {
lock: 'click to lock the tabs head',
unlock: 'click to unlock',
}
}
},
props: {
pageList: Array,
active: String,
fixed: Boolean
},
data() {
return {
affixed: false,
}
},
inject:['adminLayout'],
watch: {
'adminLayout.collapsed': (val) => {
console.log(val)
}
},
created() {
this.affixed = this.fixedTabs
},
computed: {
...mapState('setting', ['layout', 'pageWidth', 'fixedHeader', 'fixedTabs']),
lockTitle() {
return this.$t(this.fixedTabs ? 'unlock' : 'lock')
}
},
methods: {
...mapMutations('setting', ['setFixedTabs']),
onLockClick() {
this.setFixedTabs(!this.fixedTabs)
if (this.fixedTabs) {
setTimeout(() => {
this.affixed = true
}, 200)
} else {
this.affixed = false
}
},
onChange(key) {
this.$emit('change', key)
},
onEdit(key, action) {
if (action === 'remove') {
this.$emit('close', key)
}
},
onContextmenu(e) {
this.$emit('contextmenu', e)
},
pageName(page) {
return this.$t(getI18nKey(page.keyPath))
}
}
}
</script>
<style scoped lang="less">
.tabs-head{
margin: 0 auto;
&.head.fixed{
width: 1400px;
}
}
.tabs-container{
margin: -16px auto 8px;
transition: top,left 0.2s;
.header-lock{
font-size: 18px;
cursor: pointer;
color: @primary-3;
&:hover{
color: @primary-color;
}
}
&.affixed{
margin: 0 auto;
top: 0px;
padding: 8px 24px 0;
position: fixed;
height: 48px;
z-index: 1;
background-color: @layout-body-background;
&.side,&.mix{
right: 0;
left: 256px;
&.collapsed{
left: 80px;
}
}
&.head{
width: inherit;
padding: 8px 0 0;
&.fluid{
left: 0;
right: 0;
padding: 8px 24px 0;
}
}
&.fixed-header{
top: 64px;
}
}
}
.virtual-tabs{
height: 48px;
}
</style>

@ -1,20 +1,14 @@
<template>
<admin-layout>
<contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect" />
<a-tabs
v-if="multiPage"
type="editable-card"
:active-key="activePage"
:class="['tabs-view', layout, pageWidth]"
:hide-add="true"
@change="changePage"
@edit="editPage"
@contextmenu="onContextmenu"
>
<a-tab-pane :key="page.fullPath" v-for="page in pageList">
<span slot="tab" :pagekey="page.fullPath">{{pageName(page)}}</span>
</a-tab-pane>
</a-tabs>
<tabs-head
v-if="multiPage"
:active="activePage"
:page-list="pageList"
@change="changePage"
@close="remove"
@contextmenu="onContextmenu"
/>
<div :class="['tabs-view-content', layout, pageWidth]" :style="`margin-top: ${multiPage ? -24 : 0}px`">
<page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction">
<a-keep-alive v-if="multiPage" v-model="clearCaches">
@ -33,11 +27,12 @@ import PageToggleTransition from '@/components/transition/PageToggleTransition'
import {mapState, mapMutations} from 'vuex'
import {getI18nKey} from '@/utils/routerUtil'
import AKeepAlive from '@/components/cache/AKeepAlive'
import TabsHead from '@/layouts/tabs/TabsHead'
export default {
name: 'TabsView',
i18n: require('./i18n'),
components: { PageToggleTransition, Contextmenu, AdminLayout , AKeepAlive },
components: {TabsHead, PageToggleTransition, Contextmenu, AdminLayout , AKeepAlive },
data () {
return {
clearCaches: [],

@ -91,6 +91,9 @@ export default {
},
setActivatedFirst(state, activatedFirst) {
state.activatedFirst = activatedFirst
},
setFixedTabs(state, fixedTabs) {
state.fixedTabs = fixedTabs
}
}
}

Loading…
Cancel
Save