| <!-- |
| # |
| # MIT License |
| # |
| # Copyright (c) 2018 Chong Guo |
| # |
| # Permission is hereby granted, free of charge, to any person obtaining a copy |
| # of this software and associated documentation files (the "Software"), to deal |
| # in the Software without restriction, including without limitation the rights |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| # copies of the Software, and to permit persons to whom the Software is |
| # furnished to do so, subject to the following conditions: |
| # |
| # The above copyright notice and this permission notice shall be included in all |
| # copies or substantial portions of the Software. |
| # |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| # SOFTWARE. |
| # |
| --> |
| |
| <template> |
| <div |
| :class="classObj" |
| class="app-wrapper" |
| > |
| <div |
| v-if="classObj.mobile && sidebar.opened" |
| class="drawer-bg" |
| @click="handleClickOutside" |
| /> |
| <sidebar class="sidebar-container" /> |
| <div |
| :class="{hasTagsView: showTagsView}" |
| class="main-container" |
| > |
| <div :class="{'fixed-header': fixedHeader}"> |
| <navbar /> |
| <tags-view v-if="showTagsView" /> |
| </div> |
| <app-main /> |
| </div> |
| </div> |
| </template> |
| |
| <script lang="ts"> |
| import { Component } from 'vue-property-decorator' |
| import { mixins } from 'vue-class-component' |
| import { DeviceType, AppModule } from '@/store/modules/app' |
| import { SettingsModule } from '@/store/modules/settings' |
| import { AppMain, Navbar, Sidebar, TagsView } from './components' |
| import ResizeMixin from './mixin/resize' |
| |
| @Component({ |
| name: 'Layout', |
| components: { |
| AppMain, |
| Navbar, |
| Sidebar, |
| TagsView |
| } |
| }) |
| export default class extends mixins(ResizeMixin) { |
| get classObj() { |
| return { |
| hideSidebar: !this.sidebar.opened, |
| openSidebar: this.sidebar.opened, |
| withoutAnimation: this.sidebar.withoutAnimation, |
| mobile: this.device === DeviceType.Mobile |
| } |
| } |
| |
| get showSettings() { |
| return SettingsModule.showSettings |
| } |
| |
| get showTagsView() { |
| return SettingsModule.showTagsView |
| } |
| |
| get fixedHeader() { |
| return SettingsModule.fixedHeader |
| } |
| |
| private handleClickOutside() { |
| AppModule.CloseSideBar(false) |
| } |
| } |
| </script> |
| |
| <style lang="scss" scoped> |
| .app-wrapper { |
| @include clearfix; |
| position: relative; |
| height: 100%; |
| width: 100%; |
| } |
| |
| .drawer-bg { |
| background: #000; |
| opacity: 0.3; |
| width: 100%; |
| top: 0; |
| height: 100%; |
| position: absolute; |
| z-index: 999; |
| } |
| |
| .main-container { |
| min-height: 100%; |
| transition: margin-left .28s; |
| margin-left: $sideBarWidth; |
| position: relative; |
| } |
| |
| .sidebar-container { |
| transition: width 0.28s; |
| width: $sideBarWidth !important; |
| height: 100%; |
| position: fixed; |
| font-size: 0px; |
| top: 0; |
| bottom: 0; |
| left: 0; |
| z-index: 1001; |
| overflow: hidden; |
| } |
| |
| .fixed-header { |
| position: fixed; |
| top: 0; |
| right: 0; |
| z-index: 9; |
| width: calc(100% - #{$sideBarWidth}); |
| transition: width 0.28s; |
| } |
| |
| .hideSidebar { |
| .main-container { |
| margin-left: 54px; |
| } |
| |
| .sidebar-container { |
| width: 54px !important; |
| } |
| |
| .fixed-header { |
| width: calc(100% - 54px) |
| } |
| } |
| |
| /* for mobile response 适配移动端 */ |
| .mobile { |
| .main-container { |
| margin-left: 0px; |
| } |
| |
| .sidebar-container { |
| transition: transform .28s; |
| width: $sideBarWidth !important; |
| } |
| |
| &.openSidebar { |
| position: fixed; |
| top: 0; |
| } |
| |
| &.hideSidebar { |
| .sidebar-container { |
| pointer-events: none; |
| transition-duration: 0.3s; |
| transform: translate3d(-$sideBarWidth, 0, 0); |
| } |
| } |
| |
| .fixed-header { |
| width: 100%; |
| } |
| } |
| |
| .withoutAnimation { |
| .main-container, |
| .sidebar-container { |
| transition: none; |
| } |
| } |
| </style> |