django-vue-admin/web/src/layout/header-aside/layout.vue

209 lines
6.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div
class="d2-layout-header-aside-group"
:style="styleLayoutMainGroup"
:class="{ grayMode: grayActive }"
>
<!-- 半透明遮罩 -->
<div class="d2-layout-header-aside-mask"></div>
<!-- 主体内容 -->
<div class="d2-layout-header-aside-content" flex="dir:top">
<!-- 顶栏 -->
<div
class="d2-theme-header"
:style="{ opacity: this.searchActive ? 0.5 : 1 }"
flex-box="0"
flex
>
<router-link
to="/index"
:class="{ 'logo-group': true, 'logo-transition': asideTransition }"
:style="{ width: asideCollapse ? asideWidthCollapse : asideWidth }"
flex-box="0"
>
<img
v-if="asideCollapse"
:src="`${$baseUrl}image/theme/${themeActiveSetting.name}/logo/icon-only.png`"
/>
<img
v-else
:src="`${$baseUrl}image/theme/${themeActiveSetting.name}/logo/all.png`"
/>
</router-link>
<div class="toggle-aside-btn" @click="handleToggleAside" flex-box="0">
<d2-icon name="bars" />
</div>
<d2-menu-header flex-box="1" />
<!-- 顶栏右侧 -->
<div class="d2-header-right" flex-box="0">
<!-- 如果你只想在开发环境显示这个按钮请添加 v-if="$env === 'development'" -->
<d2-header-search @click="handleSearchClick" />
<d2-header-log />
<d2-header-fullscreen />
<d2-header-theme />
<d2-header-size />
<d2-header-locales />
<d2-header-color />
<d2-header-user />
</div>
</div>
<!-- 下面 主体 -->
<div class="d2-theme-container" flex-box="1" flex>
<!-- 主体 侧边栏 -->
<div
flex-box="0"
ref="aside"
:class="{
'd2-theme-container-aside': true,
'd2-theme-container-transition': asideTransition,
}"
:style="{
width: asideCollapse ? asideWidthCollapse : asideWidth,
opacity: this.searchActive ? 0.5 : 1,
}"
>
<d2-menu-side />
</div>
<!-- 主体 -->
<div class="d2-theme-container-main" flex-box="1" flex>
<!-- 搜索 -->
<transition name="fade-scale">
<div v-if="searchActive" class="d2-theme-container-main-layer" flex>
<d2-panel-search ref="panelSearch" @close="searchPanelClose" />
</div>
</transition>
<!-- 内容 -->
<transition name="fade-scale">
<div
v-if="!searchActive"
class="d2-theme-container-main-layer"
flex="dir:top"
>
<!-- tab -->
<div class="d2-theme-container-main-header" flex-box="0">
<d2-tabs />
</div>
<!-- 页面 -->
<div class="d2-theme-container-main-body" flex-box="1">
<transition :name="transitionActive ? 'fade-transverse' : ''">
<keep-alive :include="keepAlive" v-if="showView">
<router-view :key="routerViewKey" />
</keep-alive>
</transition>
</div>
</div>
</transition>
</div>
</div>
</div>
</div>
</template>
<script>
import d2MenuSide from './components/menu-side'
import d2MenuHeader from './components/menu-header'
import d2Tabs from './components/tabs'
import d2HeaderFullscreen from './components/header-fullscreen'
import d2HeaderLocales from './components/header-locales'
import d2HeaderSearch from './components/header-search'
import d2HeaderSize from './components/header-size'
import d2HeaderTheme from './components/header-theme'
import d2HeaderUser from './components/header-user'
import d2HeaderLog from './components/header-log'
import d2HeaderColor from './components/header-color'
import { mapState, mapGetters, mapActions } from 'vuex'
import mixinSearch from './mixins/search'
export default {
name: 'd2-layout-header-aside',
mixins: [mixinSearch],
components: {
d2MenuSide,
d2MenuHeader,
d2Tabs,
d2HeaderFullscreen,
d2HeaderLocales,
d2HeaderSearch,
d2HeaderSize,
d2HeaderTheme,
d2HeaderUser,
d2HeaderLog,
d2HeaderColor
},
provide () {
return {
refreshView: this.refreshView
}
},
data () {
return {
// [侧边栏宽度] 正常状态
asideWidth: '200px',
// [侧边栏宽度] 折叠状态
asideWidthCollapse: '65px',
showView: true // 用于点击当前页的router时刷新当前页
}
},
computed: {
...mapState('d2admin', {
keepAlive: (state) => state.page.keepAlive,
grayActive: (state) => state.gray.active,
transitionActive: (state) => state.transition.active,
asideCollapse: (state) => state.menu.asideCollapse,
asideTransition: (state) => state.menu.asideTransition
}),
...mapGetters('d2admin', {
themeActiveSetting: 'theme/activeSetting'
}),
/**
* @description 用来实现带参路由的缓存
*/
routerViewKey () {
// 默认情况下 key 类似 __transition-n-/foo
// 这里的字符串操作是为了最终 key 的格式和原来相同 类似 __transition-n-__stamp-time-/foo
const stamp = this.$route.meta[`__stamp-${this.$route.path}`] || ''
return `${stamp ? `__stamp-${stamp}-` : ''}${this.$route.path}`
},
/**
* @description 最外层容器的背景图片样式
*/
styleLayoutMainGroup () {
return this.themeActiveSetting.backgroundImage
? {
backgroundImage: `url('${this.$baseUrl}${this.themeActiveSetting.backgroundImage}')`
}
: {}
}
},
methods: {
...mapActions('d2admin/menu', ['asideCollapseToggle']),
/**
* 接收点击切换侧边栏的按钮
*/
handleToggleAside () {
this.asideCollapseToggle()
},
/**
* 刷新页面
*/
refreshView () {
this.showView = false // 通过v-if移除router-view节点
this.$nextTick(() => {
this.showView = true // DOM更新后再通过v-if添加router-view节点
})
}
},
mounted () {
this.$websocket.initWebSocket()
},
destroyed () {
// 离开路由之后断开websocket连接
this.$websocket.close()
}
}
</script>
<style lang="scss">
//
@import "~@/assets/style/theme/register.scss";
</style>