ai-manus/chat-client/library/layouts/index.vue

166 lines
3.6 KiB
Vue
Raw Permalink Normal View History

2025-07-18 16:38:18 +08:00
<template>
<div class="vue-admin-better-wrapper" :class="{ mobile }">
<component
:is="'vab-layout-' + theme.layout"
:has-menu="hasMenu"
:collapse="collapse"
:device="device"
:fixed-header="theme.fixedHeader"
:show-tabs="theme.showTabs"
/>
<el-backtop target="#app" />
<!-- 主题组件放到layouts下防止主题切换导致主题组件重新加载 -->
<vab-theme-drawer />
<vab-theme-setting />
</div>
</template>
<script lang="ts">
import { useSettingsStore } from '@/store/modules/settings'
const imports = require.context('./', true, /\.vue$/)
const Components: any = {}
imports
.keys()
.filter((key) => key !== './index.vue')
.forEach((key) => {
Components[key.replace(/(\/|\.|index.vue)/g, '')] = imports(key).default
})
export default defineComponent({
name: 'Layouts',
components: Components,
setup() {
const settingsStore = useSettingsStore()
const { device, collapse, hasMenu, theme } = storeToRefs(settingsStore)
const { toggleDevice, foldSideBar, openSideBar, updateTheme } = settingsStore
const mobile = ref(false)
let oldLayout = theme.value.layout
const resizeBody = () => {
mobile.value = document.body.getBoundingClientRect().width - 1 < 992
}
watch(mobile, (val) => {
if (val) {
oldLayout = theme.value.layout
foldSideBar()
} else openSideBar()
theme.value.layout = val ? 'vertical' : oldLayout
toggleDevice(val ? 'mobile' : 'desktop')
})
resizeBody()
updateTheme()
const cleanup = useEventListener('resize', () => {
resizeBody()
})
onUnmounted(() => {
if (mobile) theme.value.layout = oldLayout
cleanup()
})
return {
theme,
device,
mobile,
collapse,
hasMenu,
foldSideBar,
openSideBar,
toggleDevice,
}
},
})
</script>
<style lang="scss" scoped>
.vue-admin-better-wrapper {
position: relative;
width: 100%;
height: 100%;
[class*='vab-layout-'] {
:deep() {
.vab-layout-header {
box-shadow: $base-box-shadow;
}
}
&.fixed {
padding-top: $base-nav-height + $base-tabs-height;
}
&.fixed.no-tabs-bar {
padding-top: $base-nav-height;
}
}
:deep() {
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: $base-z-index - 1;
width: 100%;
}
.vab-main {
position: relative;
width: auto;
min-height: 100%;
margin-left: var(--el-left-menu-width);
&.is-collapse-main {
margin-left: $base-left-menu-width-min;
.fixed-header {
width: $base-right-content-width-min;
}
}
&.is-hasMenu-main {
margin-left: 0px;
}
&:not(.is-collapse-main) {
.fixed-header {
width: calc(100% - var(--el-left-menu-width));
}
}
}
}
/* 手机端开始 */
&.mobile {
:deep() {
.vab-layout-vertical {
.el-scrollbar.vab-side-bar.is-collapse {
width: 0;
}
.vab-main {
.fixed-header {
width: 100%;
}
margin-left: 0;
}
}
/* 隐藏分页和页码跳转 */
.el-pager,
.el-pagination__jump {
display: none;
}
}
}
/* 手机端结束 */
}
</style>