方案介绍:使用"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文件其他内容
参考:大屏适配解决方案