This commit is contained in:
parent
55b003c2bf
commit
32f0978108
15
src/App.vue
15
src/App.vue
|
|
@ -1,15 +1,20 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<MobileScale
|
||||
:design-width="1920"
|
||||
:min-scale="0.6"
|
||||
:breakpoint="992"
|
||||
>
|
||||
<TopLoading ref="topLoadingRef" />
|
||||
<KeepAlive>
|
||||
<router-view></router-view>
|
||||
</KeepAlive>
|
||||
</div>
|
||||
</MobileScale>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import TopLoading from '@/components/common/TopLoading.vue'
|
||||
import MobileScale from '@/components/common/MobileScale.vue'
|
||||
import { useTabsStore } from '@/stores/modules/tabs'
|
||||
|
||||
const tabsStore = useTabsStore()
|
||||
|
|
@ -27,10 +32,4 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* 移动端 viewport 缩放方案
|
||||
*
|
||||
* 功能说明:
|
||||
* 1. PC 端保持原有布局不变
|
||||
* 2. 移动端通过动态调整 viewport scale 等比例缩放
|
||||
* 3. 滚动功能正常工作
|
||||
* 4. 有最小缩放值限制,防止内容过小
|
||||
*
|
||||
* 使用方式:
|
||||
* 在 App.vue 中引入并使用
|
||||
*/
|
||||
|
||||
<template>
|
||||
<div class="mobile-scale-wrapper">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 移动端 viewport 缩放组件
|
||||
*
|
||||
* 使用 viewport 缩放实现整体缩放,滚动功能正常工作
|
||||
*
|
||||
* Props:
|
||||
* - designWidth: 设计稿宽度,默认 1920
|
||||
* - minScale: 最小缩放比例,默认 0.5
|
||||
* - breakpoint: 移动端断点,默认 992
|
||||
*/
|
||||
const props = withDefaults(defineProps<{
|
||||
designWidth?: number
|
||||
minScale?: number
|
||||
breakpoint?: number
|
||||
}>(), {
|
||||
designWidth: 1920,
|
||||
minScale: 0.5,
|
||||
breakpoint: 992,
|
||||
})
|
||||
|
||||
// 当前缩放比例
|
||||
const currentScale = ref(1)
|
||||
|
||||
// 设置 viewport meta 标签
|
||||
const setViewportMeta = (scale: number) => {
|
||||
const viewportMeta = document.querySelector('meta[name="viewport"]')
|
||||
if (viewportMeta) {
|
||||
viewportMeta.setAttribute(
|
||||
'content',
|
||||
`width=device-width, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算缩放比例
|
||||
const calculateScale = () => {
|
||||
const windowWidth = window.innerWidth
|
||||
|
||||
if (windowWidth >= props.breakpoint) {
|
||||
// PC 端:恢复默认 viewport
|
||||
currentScale.value = 1
|
||||
setViewportMeta(1)
|
||||
return
|
||||
}
|
||||
|
||||
// 计算缩放比例:屏幕宽度 / 设计稿宽度
|
||||
let calculatedScale = windowWidth / props.designWidth
|
||||
|
||||
// 限制最小缩放比例
|
||||
calculatedScale = Math.max(props.minScale, calculatedScale)
|
||||
|
||||
currentScale.value = calculatedScale
|
||||
setViewportMeta(calculatedScale)
|
||||
}
|
||||
|
||||
// 监听窗口大小变化
|
||||
const handleResize = () => {
|
||||
calculateScale()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
calculateScale()
|
||||
window.addEventListener('resize', handleResize)
|
||||
window.addEventListener('orientationchange', handleResize)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
window.removeEventListener('orientationchange', handleResize)
|
||||
// 组件销毁时恢复默认 viewport
|
||||
setViewportMeta(1)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mobile-scale-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue