190 lines
4.4 KiB
Vue
190 lines
4.4 KiB
Vue
<template>
|
||
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme, '--current-color-light': theme + '1a', '--current-color-dark-bg': theme + '33'}">
|
||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||
|
||
<!-- 顶部全宽 Header -->
|
||
<div class="top-header">
|
||
<div class="top-header__left">
|
||
<hamburger
|
||
v-if="device === 'mobile'"
|
||
id="mobile-hamburger"
|
||
:is-active="sidebar.opened"
|
||
class="mobile-hamburger"
|
||
@toggleClick="toggleSideBar"
|
||
/>
|
||
<span class="sys-title">教学管理信息系统</span>
|
||
</div>
|
||
<semester-bar class="top-header__center" />
|
||
<navbar class="top-header__right" @setLayout="setLayout" :header-mode="true" />
|
||
</div>
|
||
|
||
<!-- 下方:侧边栏 + 主内容 -->
|
||
<div class="lower-container" :class="{sidebarHide:sidebar.hide}">
|
||
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
||
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
||
<tags-view v-if="needTagsView"/>
|
||
<app-main/>
|
||
<settings ref="settingRef"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
|
||
import SemesterBar from './components/SemesterBar'
|
||
import Hamburger from '@/components/Hamburger'
|
||
import ResizeMixin from './mixin/ResizeHandler'
|
||
import { mapState } from 'vuex'
|
||
import variables from '@/assets/styles/variables.scss'
|
||
|
||
export default {
|
||
name: 'Layout',
|
||
components: {
|
||
AppMain,
|
||
Navbar,
|
||
Settings,
|
||
Sidebar,
|
||
TagsView,
|
||
SemesterBar,
|
||
Hamburger
|
||
},
|
||
mixins: [ResizeMixin],
|
||
computed: {
|
||
...mapState({
|
||
theme: state => state.settings.theme,
|
||
sideTheme: state => state.settings.sideTheme,
|
||
sidebar: state => state.app.sidebar,
|
||
device: state => state.app.device,
|
||
needTagsView: state => state.settings.tagsView
|
||
}),
|
||
classObj() {
|
||
return {
|
||
hideSidebar: !this.sidebar.opened,
|
||
mobile: this.device === 'mobile'
|
||
}
|
||
},
|
||
variables() {
|
||
return variables
|
||
}
|
||
},
|
||
methods: {
|
||
handleClickOutside() {
|
||
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
|
||
},
|
||
toggleSideBar() {
|
||
this.$store.dispatch('app/toggleSideBar')
|
||
},
|
||
setLayout() {
|
||
this.$refs.settingRef.openSetting()
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import "~@/assets/styles/mixin.scss";
|
||
@import "~@/assets/styles/variables.scss";
|
||
|
||
.app-wrapper {
|
||
@include clearfix;
|
||
position: relative;
|
||
height: 100%;
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* 顶部全宽 Header */
|
||
.top-header {
|
||
flex-shrink: 0;
|
||
height: 60px;
|
||
display: flex;
|
||
align-items: center;
|
||
background: var(--edu-green-primary);
|
||
background: linear-gradient(90deg, var(--edu-green-primary) 0%, var(--edu-green-dark) 100%);
|
||
box-shadow: 0 2px 8px rgba(0, 21, 41, 0.16);
|
||
padding: 0 20px;
|
||
z-index: 10;
|
||
|
||
&__left {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-shrink: 0;
|
||
height: 100%;
|
||
gap: 14px;
|
||
|
||
.mobile-hamburger {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 36px;
|
||
width: 36px;
|
||
border-radius: 8px;
|
||
cursor: pointer;
|
||
color: #fff;
|
||
transition: background 0.25s ease;
|
||
|
||
&:hover {
|
||
background: rgba(255, 255, 255, 0.15);
|
||
}
|
||
}
|
||
|
||
.sys-title {
|
||
font-size: 19px;
|
||
font-weight: 700;
|
||
color: #fff;
|
||
white-space: nowrap;
|
||
letter-spacing: 1.5px;
|
||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
|
||
}
|
||
}
|
||
|
||
&__center {
|
||
flex: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
justify-content: center;
|
||
height: 100%;
|
||
}
|
||
|
||
&__right {
|
||
flex-shrink: 0;
|
||
height: 100%;
|
||
}
|
||
}
|
||
|
||
/* 下方主体 */
|
||
.lower-container {
|
||
flex: 1;
|
||
min-height: 0;
|
||
display: flex;
|
||
position: relative;
|
||
}
|
||
|
||
.sidebar-container {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.main-container {
|
||
flex: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
position: relative;
|
||
overflow: hidden;
|
||
height: 100%;
|
||
background-color: #f5f7fa;
|
||
}
|
||
|
||
.drawer-bg {
|
||
background: #000;
|
||
opacity: 0.3;
|
||
width: 100%;
|
||
top: 0;
|
||
height: 100%;
|
||
position: absolute;
|
||
z-index: 999;
|
||
}
|
||
</style>
|