| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| <template> |
| <a-layout class="layout" :class="[device]"> |
| |
| <template v-if="isSideMenu()"> |
| <a-drawer |
| v-if="isMobile()" |
| :wrapClassName="'drawer-sider ' + navTheme" |
| :closable="false" |
| :visible="collapsed" |
| placement="left" |
| @close="() => this.collapsed = false" |
| > |
| <side-menu |
| :menus="menus" |
| :theme="navTheme" |
| :collapsed="false" |
| :collapsible="true" |
| mode="inline" |
| @menuSelect="menuSelect"></side-menu> |
| </a-drawer> |
| |
| <side-menu |
| v-else |
| mode="inline" |
| :menus="menus" |
| :theme="navTheme" |
| :collapsed="collapsed" |
| :collapsible="true"></side-menu> |
| </template> |
| <!-- 下次优化这些代码 --> |
| <template v-else> |
| <a-drawer |
| v-if="isMobile()" |
| :wrapClassName="'drawer-sider ' + navTheme" |
| placement="left" |
| @close="() => this.collapsed = false" |
| :closable="false" |
| :visible="collapsed" |
| > |
| <side-menu |
| :menus="menus" |
| :theme="navTheme" |
| :collapsed="false" |
| :collapsible="true" |
| mode="inline" |
| @menuSelect="menuSelect"></side-menu> |
| </a-drawer> |
| </template> |
| |
| <a-layout :class="[layoutMode, `content-width-${contentWidth}`]" :style="{ paddingLeft: contentPaddingLeft, minHeight: '100vh' }"> |
| <!-- layout header --> |
| <global-header |
| :mode="layoutMode" |
| :menus="menus" |
| :theme="navTheme" |
| :collapsed="collapsed" |
| :device="device" |
| @toggle="toggle" |
| /> |
| |
| <!-- layout content --> |
| <a-layout-content class="layout-content" :class="{'is-header-fixed': fixedHeader}"> |
| <slot></slot> |
| </a-layout-content> |
| |
| <!-- layout footer --> |
| <a-layout-footer style="padding: 0"> |
| <global-footer /> |
| </a-layout-footer> |
| </a-layout> |
| </a-layout> |
| </template> |
| |
| <script> |
| import SideMenu from '@/components/menu/SideMenu' |
| import GlobalHeader from '@/components/page/GlobalHeader' |
| import GlobalFooter from '@/components/page/GlobalFooter' |
| import { triggerWindowResizeEvent } from '@/utils/util' |
| import { mapState, mapActions } from 'vuex' |
| import { mixin, mixinDevice } from '@/utils/mixin.js' |
| |
| export default { |
| name: 'GlobalLayout', |
| components: { |
| SideMenu, |
| GlobalHeader, |
| GlobalFooter |
| }, |
| mixins: [mixin, mixinDevice], |
| data () { |
| return { |
| collapsed: false, |
| menus: [] |
| } |
| }, |
| computed: { |
| ...mapState({ |
| // 主路由 |
| mainMenu: state => state.permission.addRouters |
| }), |
| contentPaddingLeft () { |
| if (!this.fixSidebar || this.isMobile()) { |
| return '0' |
| } |
| if (this.sidebarOpened) { |
| return '256px' |
| } |
| return '80px' |
| } |
| }, |
| watch: { |
| sidebarOpened (val) { |
| this.collapsed = !val |
| } |
| }, |
| created () { |
| this.menus = this.mainMenu.find((item) => item.path === '/').children |
| this.collapsed = !this.sidebarOpened |
| }, |
| mounted () { |
| const userAgent = navigator.userAgent |
| if (userAgent.indexOf('Edge') > -1) { |
| this.$nextTick(() => { |
| this.collapsed = !this.collapsed |
| setTimeout(() => { |
| this.collapsed = !this.collapsed |
| }, 16) |
| }) |
| } |
| }, |
| methods: { |
| ...mapActions(['setSidebar']), |
| toggle () { |
| this.collapsed = !this.collapsed |
| this.setSidebar(!this.collapsed) |
| triggerWindowResizeEvent() |
| }, |
| paddingCalc () { |
| let left = '' |
| if (this.sidebarOpened) { |
| left = this.isDesktop() ? '256px' : '80px' |
| } else { |
| left = this.isMobile() && '0' || (this.fixSidebar && '80px' || '0') |
| } |
| return left |
| }, |
| menuSelect () { |
| if (!this.isDesktop()) { |
| this.collapsed = false |
| } |
| } |
| } |
| } |
| </script> |
| |
| <style lang="less"> |
| .layout-content { |
| &.is-header-fixed { |
| margin: 78px 12px 0; |
| } |
| } |
| |
| // Todo try to get this rules scoped |
| .ant-drawer.drawer-sider { |
| .sider { |
| box-shadow: none; |
| } |
| |
| &.dark { |
| .ant-drawer-content { |
| background-color: rgb(0, 21, 41); |
| } |
| } |
| |
| &.light { |
| box-shadow: none; |
| |
| .ant-drawer-content { |
| background-color: #fff; |
| } |
| } |
| |
| .ant-drawer-body { |
| padding: 0 |
| } |
| } |
| </style> |