Files
sunProduct/src/layout/index.vue

194 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 👇 加这一层全局缩放容器 -->
<div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
<side-bar class="sidebar-container" />
<div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container" id="main-container">
<div class="navbarContant">
<navbar ref="navbarRef" @set-layout="setLayout" />
</div>
<app-main />
<i class="bgColor" v-if="bgColorStore.isShow"></i>
<settings ref="settingRef" />
</div>
</div>
</template>
<script setup lang="ts">
// ==========================================
// ✅ 第1步:统一 import
// ==========================================
import { ref, computed, watchEffect, onMounted, onUnmounted } from 'vue';
import { useWindowSize } from '@vueuse/core';
import SideBar from './components/Sidebar/index.vue';
import { AppMain, Navbar, Settings } from './components';
import { useAppStore } from '@/store/modules/app';
import { useSettingsStore } from '@/store/modules/settings';
// import { NavTypeEnum } from '@/enums/NavTypeEnum';
import { useBgColor } from '@/store/modules/bgColor';
import { initWebSocket } from '@/utils/websocket';
import { initSSE } from '@/utils/sse';
const bgColorStore = useBgColor();
// ==========================================
// ✅ 第2步:缩放逻辑(从旧 script 移过来)
// ==========================================
const scale = ref(1);
const DESIGN_WIDTH = 1920;
const calcScale = () => {
const width = document.documentElement.clientWidth;
let ratio = width / DESIGN_WIDTH;
if (ratio < 0.7) ratio = 0.7;
if (ratio > 1) ratio = 1;
scale.value = ratio;
};
let timer: any = null;
const resize = () => {
clearTimeout(timer);
timer = setTimeout(calcScale, 100);
};
// ==========================================
// ✅ 第3步:生命周期钩子(统一写在这里)
// ==========================================
onMounted(() => {
// 缩放初始化
calcScale();
window.addEventListener('resize', resize);
// WebSocket
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
initWebSocket(protocol + window.location.host + import.meta.env.VITE_APP_BASE_API + '/resource/websocket');
// SSE
initSSE(import.meta.env.VITE_APP_BASE_API + '/resource/sse');
});
onUnmounted(() => {
window.removeEventListener('resize', resize);
clearTimeout(timer);
});
// ==========================================
// ✅ 第4步:原有业务逻辑
// ==========================================
const settingsStore = useSettingsStore();
const theme = computed(() => settingsStore.theme);
const sidebar = computed(() => useAppStore().sidebar);
const device = computed(() => useAppStore().device);
const needTagsView = computed(() => settingsStore.tagsView);
// const fixedHeader = computed(() => settingsStore.fixedHeader);
// const layout = computed(() => settingsStore.navType);
// const showSidebar = computed(() => {
// if (sidebar.value.hide) return false;
// return layout.value === NavTypeEnum.LEFT || layout.value === NavTypeEnum.MIX;
// });
const classObj = computed(() => ({
hideSidebar: !sidebar.value.opened,
openSidebar: sidebar.value.opened,
withoutAnimation: sidebar.value.withoutAnimation,
mobile: device.value === 'mobile'
}));
const { width } = useWindowSize();
const WIDTH = 992;
watchEffect(() => {
if (device.value === 'mobile') {
useAppStore().closeSideBar({ withoutAnimation: false });
}
if (width.value - 1 < WIDTH) {
useAppStore().toggleDevice('mobile');
useAppStore().closeSideBar({ withoutAnimation: true });
} else {
useAppStore().toggleDevice('desktop');
}
});
const navbarRef = ref<InstanceType<typeof Navbar>>();
const settingRef = ref<InstanceType<typeof Settings>>();
// const handleClickOutside = () => {
// useAppStore().closeSideBar({ withoutAnimation: false });
// };
const setLayout = () => {
settingRef.value?.openSetting();
};
</script>
<style lang="scss" scoped>
@use '@/assets/styles/mixin.scss';
@use '@/assets/styles/variables.module.scss' as *;
.app-wrapper {
@include mixin.clearfix;
position: relative;
height: 100%;
width: 100%;
display: flex;
align-items: center;
&.mobile.openSidebar {
position: fixed;
top: 0;
}
}
.main-container {
flex: 1;
background-color: #dfedff;
}
.navbarContant {
position: relative;
z-index: 100;
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{$base-sidebar-width});
transition: width 0.28s;
background: $fixed-header-bg;
}
.hideSidebar .fixed-header {
width: calc(100% - 54px);
}
.sidebarHide .fixed-header {
width: 100%;
}
.mobile .fixed-header {
width: 100%;
}
.bgColor {
width: 850px;
height: 850px;
background: #fdf1ee;
filter: blur(200px);
display: block;
position: absolute;
top: -50%;
right: -10%;
pointer-events: none;
z-index: 1;
border-radius: 50%;
}
</style>