大屏适配解决方案vue3版本

2,624 阅读1分钟

方案介绍:使用"transform:scale"在vue3项目实现大屏适配,下面代码适用于包裹整个页面即App.vue。本方案把宽度、高度也进行了自适应,可以根据自己实际情况删除setScale()中倒数第2、3行代码。

如果只想包裹页面某个区域,ScreenAdapter.vue不能直接放在App.vue的顶层template标签紧邻位置,而且需要修改宽高值,比如顶部有菜单,我只想对菜单下的页面进行自适应,菜单高度为80px,则代码中fixedHeight变量和setScale函数中的style.value.height的值需要在原基础值上减去80px。

直接上代码:

步骤1:写自适应组件
ScreenAdapter.vue:

<template>
    <div class="screen-adapter-style" :style="style"> 
        <slot />
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';

// 用于getScale()函数
const fixedWidth = ref(document.documentElement.clientWidth.toString());
const fixedHeight = ref(document.documentElement.clientHeight.toString());

// 默认行内样式
const style = ref({
    'width': `${fixedWidth.value}px`,
    'height':  `${fixedHeight.value}px`,
    'transform': 'scale(1) translate(-50% -50%)',
})

onMounted(()=>{
    setScale(); // 初始化时就执行一次setScale
    window.onresize = debounce(setScale, 1000); // 监听onresize事件,执行setSacle
})

const debounce = (fn, delay)=>{
    let timer;
    console.log('执行了debounce'); // 只执行一次,下面紧邻函数内的代码会在每次触发resize事件时执行
    return function(){
        // const args = arguments; // fn函数(即setScale函数)不必使用args作为fn的入参,
        // apply()方法作用:https://blog.csdn.net/weixin_43877799/article/details/120282509
        if(timer){
            clearTimeout(timer);
        }
        const context = this;
        timer = setTimeout(()=>{
            timer = null;
            console.log('正在执行自适应');
            fn.apply(context); // 或者可以直接运行fn();
        }, delay);
    }
}

// 获取放大缩小比例
const getScale = ()=>{
    const w = window.innerWidth / fixedWidth.value;
    const h = window.innerHeight / fixedHeight.value;
    return w<h? w: h;
}

// 修改样式
const setScale = ()=>{
    style.value.transform =  `scale${getScale()})) translate(-50% -50%)`;
    // 宽高自适应,window.innerWidth见文章:https://juejin.cn/post/6844903598489337869
    style.value.width =  `${(window.innerWidth).toString()}px`; // 赋值时不要使用document.documentElement.clientWidth
    style.value.height =  `${(window.innerHeight).toString()}px`;// 赋值时不要使用document.documentElement.clientHeight
    console.log('自适应后的style', style.value);
}
</script>

<style scoped lang="scss">
.screen-adapter-style{
    transform-origin: 0 0;
    position: absolute;
    left: 50%;
     top: 50%;
    transition: 0.3s; // 增大该值可以比较明显地看到自适应过程
    background: transparent; // 可以调整背景色
}
</style>

步骤2:在main.js中全局注册ScreenAdapter组件:
main.js:

import {createApp} from 'vue';
import ScreenAdapter from "@/components/ScreenAdapter.vue";
import App from './App.vue';

const APP = createApp(App);
APP.component('screen-adapter', ScreenAdapter);

步骤3.把ScreenAdapter组件包裹在App.vue的顶层div中,即template的下一级
App.vue:

<template>
    <screen-adapter>
      <router-view></router-view>
    </screen-adapter>
</template>
 // App.vue文件其他内容

参考:大屏适配解决方案