大屏自适应之前有用过postcss-pxtorem之类的插件,但是插件只针对css样式,在js和vue模板中的样式,还有echarts的属性值都不能经过插件直接转换。要手动分装方法再次调用,就会比较麻烦,而且有时候写着写着就忘加了,开发就一个分辨率的显示器,最多就是f12打开挤兑挤兑测测。
解决方案 ------- 缩放 + scrollbar(非全屏)
可以使用transform: scale(${this.scale})来设置当前屏幕的缩放比例,以视觉稿为基数1,等比例缩放页面。一般来说大屏设计都是1920*1080的大小,但是浏览器的地址栏标签栏等会占掉一定的高度,所以不是全屏的时候,是显示不全的。所以当比这个比例小的时候,增加竖向滚动条,当全屏的时候,就是正常显示。有些大屏可能还会内嵌到其他框架里边,也可以给大屏增加全屏按钮。
非全屏:出滚动条,全屏: 正常显示
内嵌进其他框架,比如qiankun框架,可以给大屏自己增加全屏和取消全屏按钮,而不是使用键盘的f11
目前的问题:
1. 缩放css属性没有设置在body上,而是在body的子标签上,所以对于一些自动插入到body的元素,缩放不生效(可以试试直接将缩放属性设置在body上,因为这个问题是我用的时候才遇到的,还莫得时间去改)
2. 放大2倍之后,echarts可能看着有点糊。。。。。。。。。没有在特别大的屏上试过,只是有个功能正好做了点击再放大2倍图表,看着是有点糊。。。。。
vue2
这里我使用了ResizeObserverIns来监听dom的变化,也可以使用window的resize方法
<template>
<div class="page-screen" ref="fullScreen">
<el-scrollbar>
<div class="bg" :style="computedStyle">
...
</div>
</el-scrollbar>
</div>
</template>
<script>
let ResizeObserverIns = null
export default {
data() {
return {
scale: 1
}
},
computed: {
computedStyle() {
return {
transform: `scale(${this.scale})`,
'transform-origin': '0 0',
}
},
},
mounted() {
this.screenResize()
ResizeObserverIns = new ResizeObserver(() => {
this.screenResize()
})
ResizeObserverIns.observe(this.$refs.fullScreen)
},
beforeDestroy() {
ResizeObserverIns && ResizeObserverIns.disconnect()
},
methods: {
screenResize() {
this.scale = this.$refs.fullScreen.offsetWidth / 1920
},
}
}
</script>
<style lang="scss" scoped>
.page-screen {
width: 100%;
height: 100%;
background: rgb(4, 16, 44);
overflow: hidden;
::v-deep .el-scrollbar__wrap{
height: calc(100% + 10px);
}
::v-deep .el-scrollbar__view {
height: 100%;
}
}
.bg {
width: 1920px;
height: 1080px;
// background-image: url('@/assets/bg.png'); // 一般大屏会有背景
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
overflow: hidden;
position: relative;
}vue3
vue3只是在script写法上与vue2不一样
import { computed, ref, onMounted } from 'vue'
import { throttle } from '@/utils'
import { useScaleStore } from '@/store/scale' // 这个是pinia全局存值,类似vuex,没有用到可以忽略
const store = useScaleStore()
let ResizeObserverIns = null
let scale = ref(1)
let fullScreen = ref()
const computedStyle = computed(() => {
return {
transform: `scale(${scale.value})`,
'transform-origin': '0 0'
}
})
onMounted(() => {
screenResize()
ResizeObserverIns = new ResizeObserver(() => {
screenResize()
})
ResizeObserverIns.observe(fullScreen.value)
})
const screenResize = throttle(function () { // 增加节流,之前vue2上项目比较赶,后来也懒得加
scale.value = fullScreen.value.offsetWidth / 1920
store.changeScale(scale.value)
}, 60)全屏 / 取消全屏
screenClick() {
const fullarea = this.$refs.fullScreen
if (this.fullScreen) {
cancelScreen()
} else {
fullScreen(fullarea)
}
this.fullScreen = !this.fullScreen
}
// 工具方法
// 全屏
export const fullScreen = (fullarea) => {
if (fullarea.requestFullscreen) {
fullarea.requestFullscreen();
} else if (fullarea.webkitRequestFullScreen) {
fullarea.webkitRequestFullScreen();
} else if (fullarea.mozRequestFullScreen) {
fullarea.mozRequestFullScreen();
} else if (fullarea.msRequestFullscreen) {
// IE11
fullarea.msRequestFullscreen();
}
}
// 取消全屏
export const cancelScreen = () => {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}总结
大屏方案现在使用下来还是scale好用,写代码的时候完全不用操心,而且其他人写的时候也不会出问题
















