From 21c5a33401e07ecc04561f252cffea67954ec050 Mon Sep 17 00:00:00 2001
From: iczer <1126263215@qq.com>
Date: Sun, 21 Jun 2020 15:33:09 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E5=9B=BA=E5=AE=9AHe?=
 =?UTF-8?q?ader=E5=8A=9F=E8=83=BD=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: iczer <1126263215@qq.com>
---
 src/components/setting/Setting.vue |  7 ++++--
 src/config/index.js                |  1 +
 src/layouts/GlobalHeader.vue       | 35 +++++++++++++++---------------
 src/layouts/GlobalLayout.vue       | 23 ++++++++++++++++----
 src/layouts/HeaderNotice.vue       |  6 ++---
 src/store/modules/setting.js       |  3 +++
 6 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/src/components/setting/Setting.vue b/src/components/setting/Setting.vue
index cc0572e..d4e4eea 100644
--- a/src/components/setting/Setting.vue
+++ b/src/components/setting/Setting.vue
@@ -29,7 +29,7 @@
         </a-list-item>
         <a-list-item>
           固定Header
-          <a-switch slot="actions" size="small" />
+          <a-switch :checked="fixedHeader" slot="actions" size="small" @change="setFixedHeader" />
         </a-list-item>
         <a-list-item>
           固定Siderbar
@@ -114,7 +114,7 @@ export default {
     directions() {
       return this.animates.find(item => item.name == this.animate).directions
     },
-    ...mapState('setting', ['animates', 'multiPage', 'weekMode'])
+    ...mapState('setting', ['animates', 'multiPage', 'weekMode', 'fixedHeader'])
   },
   methods: {
     onColorChange (values, colors) {
@@ -153,6 +153,9 @@ export default {
         direction: this.direction
       }
       this.$store.commit('setting/setAnimate', animate)
+    },
+    setFixedHeader(checked) {
+      this.$store.commit('setting/setFixedHeader', checked)
     }
   }
 }
diff --git a/src/config/index.js b/src/config/index.js
index d599db8..7de7a98 100644
--- a/src/config/index.js
+++ b/src/config/index.js
@@ -3,6 +3,7 @@ module.exports = {
   themeColor: '#1890ff',
   theme: 'dark',
   layout: 'side',
+  fixedHeader: false,
   weekMode: false,
   multiPage: false,
   systemName: 'Vue Antd Admin',
diff --git a/src/layouts/GlobalHeader.vue b/src/layouts/GlobalHeader.vue
index 796d724..1fb8ce2 100644
--- a/src/layouts/GlobalHeader.vue
+++ b/src/layouts/GlobalHeader.vue
@@ -1,16 +1,16 @@
 <template>
-  <a-layout-header :class="[theme, 'global-header']">
+  <a-layout-header :class="[headerTheme, 'global-header']">
     <div :class="['global-header-wide', layout]">
-      <router-link v-if="isMobile || layout === 'head'" to="/" :class="['logo', isMobile ? null : 'pc', theme]">
+      <router-link v-if="isMobile || layout === 'head'" to="/" :class="['logo', isMobile ? null : 'pc', headerTheme]">
         <img width="32" src="@/assets/img/vue-antd-logo.png" />
         <h1 v-if="!isMobile">{{systemName}}</h1>
       </router-link>
       <a-divider v-if="isMobile" type="vertical" />
       <a-icon v-if="layout === 'side'" class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="toggleCollapse"/>
-      <div v-if="layout === 'head'" class="global-header-menu">
-        <i-menu style="height: 64px; line-height: 64px;" :theme="theme" mode="horizontal" :menuData="menuData" @select="onSelect"/>
+      <div v-if="layout == 'head' && !isMobile" class="global-header-menu">
+        <i-menu style="height: 64px; line-height: 64px;" :theme="headerTheme" mode="horizontal" :menuData="menuData" @select="onSelect"/>
       </div>
-      <div :class="['global-header-right', theme]">
+      <div :class="['global-header-right', headerTheme]">
           <header-search class="header-item" />
           <a-tooltip class="header-item" title="帮助文档" placement="bottom" >
             <a>
@@ -29,23 +29,21 @@ import HeaderSearch from './HeaderSearch'
 import HeaderNotice from './HeaderNotice'
 import HeaderAvatar from './HeaderlAvatar'
 import IMenu from '../components/menu/menu'
+import {mapState} from 'vuex'
 
 export default {
   name: 'GlobalHeader',
   components: {IMenu, HeaderAvatar, HeaderNotice, HeaderSearch},
   props: ['collapsed', 'menuData'],
+  provide() {
+    return {
+      headerTheme: this.theme
+    }
+  },
   computed: {
-    isMobile () {
-      return this.$store.state.setting.isMobile
-    },
-    layout () {
-      return this.$store.state.setting.layout
-    },
-    theme () {
-      return this.layout === 'side' ? 'light' : this.$store.state.setting.theme
-    },
-    systemName () {
-      return this.$store.state.setting.systemName
+    ...mapState('setting', ['theme', 'isMobile', 'layout', 'systemName']),
+    headerTheme () {
+      return (this.layout == 'side' && !this.isMobile) ? 'light' : this.theme
     }
   },
   methods: {
@@ -85,13 +83,16 @@ export default {
     padding: 0 12px 0 0;
     -webkit-box-shadow: 0 1px 4px rgba(0,21,41,.08);
     box-shadow: 0 1px 4px rgba(0,21,41,.08);
-    z-index: 99;
+    z-index: 1;
     position: relative;
     &.light{
       background: #fff;
     }
     &.dark{
       background: #001529;
+      .trigger{
+        color: white;
+      }
     }
     .global-header-wide{
       &.head{
diff --git a/src/layouts/GlobalLayout.vue b/src/layouts/GlobalLayout.vue
index 6913775..ceda357 100644
--- a/src/layouts/GlobalLayout.vue
+++ b/src/layouts/GlobalLayout.vue
@@ -6,12 +6,13 @@
     <sider-menu :theme="theme" v-else-if="layout === 'side'" :menuData="menuData" :collapsed="collapsed" :collapsible="true" />
     <drawer :open-drawer="showSetting" placement="right"  @change="onSettingDrawerChange">
       <div class="setting" slot="handler">
-        <a-icon :type="showSetting ? 'close' : 'setting'" />
+        <a-icon :type="showSetting ? 'close' : 'setting'"/>
       </div>
       <setting />
     </drawer>
     <a-layout class="global-layout-main">
-      <global-header :menuData="menuData" :collapsed="collapsed" @toggleCollapse="toggleCollapse"/>
+      <global-header :style="headerStyle" :menuData="menuData" :collapsed="collapsed" @toggleCollapse="toggleCollapse"/>
+      <a-layout-header v-if="fixedHeader"></a-layout-header>
       <a-layout-content class="global-layout-content">
         <div :style="`min-height: ${minHeight}px; position: relative`">
           <slot></slot>
@@ -53,7 +54,16 @@ export default {
     }
   },
   computed: {
-    ...mapState('setting', ['isMobile', 'theme', 'layout', 'footerLinks', 'copyright']),
+    ...mapState('setting', ['isMobile', 'theme', 'layout', 'footerLinks', 'copyright', 'fixedHeader']),
+    sideMenuWidth() {
+      return this.collapsed ? '80px' : '256px'
+    },
+    headerStyle() {
+      let width = (this.fixedHeader && this.layout == 'side' && !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}`
+    }
   },
   methods: {
     toggleCollapse () {
@@ -67,7 +77,7 @@ export default {
     },
     onSettingDrawerChange (val) {
       this.showSetting = val
-    }
+    },
   },
   beforeCreate () {
     menuData = this.$router.options.routes.find((item) => item.path === '/').children
@@ -83,6 +93,7 @@ export default {
       scrollbar-color: @primary-color @primary-2;
       scrollbar-width: thin;
       -ms-overflow-style:none;
+      position: relative;
       &::-webkit-scrollbar{
         width: 3px;
         height: 1px;
@@ -96,6 +107,10 @@ export default {
         border-radius: 3px;
         background: @primary-3;
       }
+      .global-header{
+        top: 0;
+        right: 0;
+      }
     }
     .global-layout-content{
       padding: 24px 24px 0;
diff --git a/src/layouts/HeaderNotice.vue b/src/layouts/HeaderNotice.vue
index c6d2836..3d3f57f 100644
--- a/src/layouts/HeaderNotice.vue
+++ b/src/layouts/HeaderNotice.vue
@@ -48,11 +48,9 @@ export default {
       loading: false
     }
   },
+  inject: 'headerTheme',
   computed: {
-    ...mapState('setting', ['layout', 'theme']),
-    headerTheme() {
-      return this.layout == 'side' ? 'light' : this.theme
-    },
+    ...mapState('setting', ['layout', 'theme'])
   },
   methods: {
     fetchNotice () {
diff --git a/src/store/modules/setting.js b/src/store/modules/setting.js
index 7b49731..3709eb9 100644
--- a/src/store/modules/setting.js
+++ b/src/store/modules/setting.js
@@ -27,6 +27,9 @@ export default {
     },
     setWeekMode(state, weekMode) {
       state.weekMode = weekMode
+    },
+    setFixedHeader(state, fixedHeader) {
+      state.fixedHeader = fixedHeader
     }
   }
 }