|
|
|
|
<template>
|
|
|
|
|
<!-- 全局容器 -->
|
|
|
|
|
<div class="app-container">
|
|
|
|
|
<!-- 路由视图容器 -->
|
|
|
|
|
<router-view v-slot="{ Component, route }">
|
|
|
|
|
<!-- 智能缓存:仅缓存带有 meta.keepAlive 的路由 -->
|
|
|
|
|
<!-- <keep-alive :include="cachedRoutes"> -->
|
|
|
|
|
<component
|
|
|
|
|
:is="Component"
|
|
|
|
|
:key="route.fullPath"
|
|
|
|
|
class="router-view-container"
|
|
|
|
|
:class="{ 'has-header': showHeader }"
|
|
|
|
|
/>
|
|
|
|
|
<!-- </keep-alive> -->
|
|
|
|
|
</router-view>
|
|
|
|
|
|
|
|
|
|
<!-- 大屏适配容器(用于缩放内容) -->
|
|
|
|
|
<div
|
|
|
|
|
v-if="isDashboardPage"
|
|
|
|
|
ref="scaleContainer"
|
|
|
|
|
class="scale-container"
|
|
|
|
|
:style="scaleStyle"
|
|
|
|
|
>
|
|
|
|
|
<!-- 实际内容会被挂载到这里 -->
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { computed, ref, onMounted, onUnmounted, watch } from 'vue'
|
|
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
const scaleContainer = ref<HTMLElement>()
|
|
|
|
|
const scaleValue = ref(1)
|
|
|
|
|
|
|
|
|
|
// 需要缓存的组件名称列表
|
|
|
|
|
const cachedRoutes = ref<string[]>([])
|
|
|
|
|
|
|
|
|
|
// 是否显示头部(根据路由配置)
|
|
|
|
|
const showHeader = computed(() => route.meta.showHeader ?? true)
|
|
|
|
|
|
|
|
|
|
// 是否大屏页面(需要特殊适配)
|
|
|
|
|
const isDashboardPage = computed(() => route.meta.isDashboard ?? false)
|
|
|
|
|
|
|
|
|
|
// 缩放样式计算
|
|
|
|
|
const scaleStyle = computed(() => ({
|
|
|
|
|
transform: `scale(${scaleValue.value}) translate(-50%, -50%)`,
|
|
|
|
|
width: `${(1 / scaleValue.value) * 100}%`,
|
|
|
|
|
height: `${(1 / scaleValue.value) * 100}%`
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
// 自适应计算函数
|
|
|
|
|
const calculateScale = () => {
|
|
|
|
|
if (!isDashboardPage.value || !scaleContainer.value) return
|
|
|
|
|
|
|
|
|
|
const baseWidth = 1920 // 设计稿基准宽度
|
|
|
|
|
const baseHeight = 1080 // 设计稿基准高度
|
|
|
|
|
const currentWidth = window.innerWidth
|
|
|
|
|
const currentHeight = window.innerHeight
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例(考虑宽高比)
|
|
|
|
|
const widthRatio = currentWidth / baseWidth
|
|
|
|
|
const heightRatio = currentHeight / baseHeight
|
|
|
|
|
scaleValue.value = Math.min(widthRatio, heightRatio)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 监听路由变化
|
|
|
|
|
watch(
|
|
|
|
|
() => route.path,
|
|
|
|
|
(newVal) => {
|
|
|
|
|
// 更新缓存路由列表
|
|
|
|
|
if (route.meta.keepAlive && route.name) {
|
|
|
|
|
cachedRoutes.value = [...new Set([...cachedRoutes.value, route.name as string])]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 大屏页面特殊处理
|
|
|
|
|
if (isDashboardPage.value) {
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
// 将路由视图移动到缩放容器
|
|
|
|
|
const view = document.querySelector('.router-view-container')
|
|
|
|
|
if (view && scaleContainer.value) {
|
|
|
|
|
scaleContainer.value.appendChild(view)
|
|
|
|
|
}
|
|
|
|
|
calculateScale()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 窗口resize监听(带防抖)
|
|
|
|
|
let resizeTimer: number
|
|
|
|
|
const onResize = () => {
|
|
|
|
|
clearTimeout(resizeTimer)
|
|
|
|
|
resizeTimer = setTimeout(calculateScale, 300)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
window.addEventListener('resize', onResize)
|
|
|
|
|
calculateScale()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
window.removeEventListener('resize', onResize)
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
/* 全局样式重置 */
|
|
|
|
|
html, body, #app {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
overflow: hidden; /* 禁用全局滚动条 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.app-container {
|
|
|
|
|
position: relative;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
/* 路由视图基础样式 */
|
|
|
|
|
.router-view-container {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 大屏适配容器样式 */
|
|
|
|
|
.scale-container {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 50%;
|
|
|
|
|
left: 50%;
|
|
|
|
|
transform-origin: 0 0;
|
|
|
|
|
transition: transform 0.3s;
|
|
|
|
|
|
|
|
|
|
/* 大屏页面特殊处理 */
|
|
|
|
|
.router-view-container {
|
|
|
|
|
background: #08104C; /* 深色背景 */
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|