Files
X-Financial/web/src/App.vue
caoxiaozhu ce04f5aa86 feat(web): update Vue components
- App.vue: update app root component
- PersonalWorkbench.vue: update personal workbench component
2026-05-12 15:39:00 +00:00

106 lines
3.1 KiB
Vue

<template>
<div class="app-desktop-shell" :style="desktopScaleStyle">
<div class="app-desktop-stage">
<RouterView />
<ToastNotification :toast-text="toastText" />
</div>
</div>
</template>
<script setup>
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { RouterView } from 'vue-router'
import './assets/styles/global.css'
import ToastNotification from './components/shared/ToastNotification.vue'
import { useToast } from './composables/useToast.js'
const { toastText } = useToast()
const DESKTOP_BASE_WIDTH = 1600
const DESKTOP_BASE_HEIGHT = 920
const DESKTOP_MIN_SCALE = 0.82
const viewportWidth = ref(typeof window === 'undefined' ? DESKTOP_BASE_WIDTH : window.innerWidth)
const viewportHeight = ref(typeof window === 'undefined' ? DESKTOP_BASE_HEIGHT : window.innerHeight)
const desktopScaleStyle = computed(() => {
const metrics = resolveDesktopMetrics(viewportWidth.value, viewportHeight.value)
return {
'--desktop-ui-scale': metrics.scale.toFixed(4),
'--desktop-ui-inverse-scale': metrics.inverseScale.toFixed(4),
'--desktop-stage-width': `${metrics.stageWidth}px`,
'--desktop-stage-height': `${metrics.stageHeight}px`
}
})
const desktopMetrics = computed(() => resolveDesktopMetrics(viewportWidth.value, viewportHeight.value))
function resolveDesktopMetrics(width, height) {
if (width < 960) {
return {
scale: 1,
inverseScale: 1,
stageWidth: width,
stageHeight: height,
viewportWidth: width,
viewportHeight: height
}
}
const scaleByWidth = width / DESKTOP_BASE_WIDTH
const scaleByHeight = height / DESKTOP_BASE_HEIGHT
const scale = Number(Math.min(1, Math.max(DESKTOP_MIN_SCALE, Math.min(scaleByWidth, scaleByHeight))).toFixed(4))
const inverseScale = Number((1 / scale).toFixed(4))
return {
scale,
inverseScale,
stageWidth: Math.round(width * inverseScale),
stageHeight: Math.round(height * inverseScale),
viewportWidth: width,
viewportHeight: height
}
}
function syncRootDesktopVars(metrics) {
if (typeof document === 'undefined') {
return
}
const rootStyle = document.documentElement.style
rootStyle.setProperty('--desktop-ui-scale', metrics.scale.toFixed(4))
rootStyle.setProperty('--desktop-ui-inverse-scale', metrics.inverseScale.toFixed(4))
rootStyle.setProperty('--desktop-stage-width', `${metrics.stageWidth}px`)
rootStyle.setProperty('--desktop-stage-height', `${metrics.stageHeight}px`)
rootStyle.setProperty('--desktop-viewport-width', String(metrics.viewportWidth))
rootStyle.setProperty('--desktop-viewport-height', String(metrics.viewportHeight))
}
function updateViewport() {
viewportWidth.value = window.innerWidth
viewportHeight.value = window.innerHeight
}
watch(
desktopMetrics,
(metrics) => {
syncRootDesktopVars(metrics)
},
{ immediate: true }
)
onMounted(() => {
updateViewport()
window.addEventListener('resize', updateViewport, { passive: true })
})
onBeforeUnmount(() => {
window.removeEventListener('resize', updateViewport)
})
</script>
<style src="./assets/styles/app.css"></style>