随着数字化转型的加速,越来越多的企业使用大屏显示数据,适配不同分辨率和设备变得至关重要。大屏的适配方案有很多,vw、vh;rem;viewpoint;transform等等,通常需要多种方案结合使用。本文介绍一下我的解决方案是如何构建出一个响应式、可维护的数字大屏架构的。
- datav的全屏容器组件
dv-full-screen-container完成初步响应式页面 - PostCSS 插件:postcss-px-to-rem将px转换成rem
- 监听屏幕resize,计算屏幕缩放比,echarts字体大小单独动态处理
- 灵活的布局策略,使用百分比和flex布局
这样的方案结合就能确保大屏在各个分辨率下都能够得到很好的展示。
datav的全屏容器组件
看了dv-full-screen-container的源码,他的实现其实也不复杂,核心就是用transform: scale() 来缩放容器。这使得内容能够根据屏幕宽度进行适当缩放,适应不同的屏幕,以保持视觉上的一致性。使用了 position: fixed,将容器固定在视口的左上角。再结合flex和百分比布局,初步的响应式设计就完成了,这样后续搭建内部的框架就很容易了。
PostCSS 插件:postcss-px-to-rem
使用插件将所有的px转换成rem单位,可以更灵活地控制字体和元素的大小、边距,也能更好地与根字体大小结合,提升适配性。 (使用px主要还是因为px用的多,比较熟练,写样式、控制大小比较方便,如果用vh、vw也是可以的。
- 值得注意的是:postcss-px-to-rem对内联样式无效,因为postcss-px-to-rem主要是针对外部样式表和css文件,将css中的px单位识别出来,按照规则转换成rem单位,而内联样式嵌入在HTML元素中,插件是无法识别的。所以要尽量避免内联,确保所有样式都能通过 PostCSS 处理。
//在vue.config.ts文件中加上以下代码
css: {
loaderOptions: {
postcss: {
plugins: [
require('@njleonzhang/postcss-px-to-rem')({
// 把px单位换算成rem单位
rootValue: 96, //换算基数,
unitPrecision: 3, //允许REM单位增长到的十进制数字,小数点后保留的位数。
propList: ['*'],
exclude: /(node_module)/, //默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
selectorBlackList: ['.van'], //要忽略并保留为px的选择器,本项目我是用的vant ui框架,所以忽略他
mediaQuery: true, //(布尔值)允许在媒体查询中转换px。
minPixelValue: 1 //设置要替换的最小像素值
})
]
}
}
}
新建rem.js文件并在main.js中引入
;(function init(screenRatioByDesign = 16 / 9) {
let docEle = document.documentElement
function setHtmlFontSize() {
var screenRatio = docEle.clientWidth / docEle.clientHeight
var fontSize =
((screenRatio > screenRatioByDesign
? screenRatioByDesign / screenRatio
: 1) *
docEle.clientWidth) /
10
docEle.style.fontSize = fontSize.toFixed(3) + 'px'
}
setHtmlFontSize()
window.addEventListener('resize', setHtmlFontSize)
})()
echarts字体大小动态设置
echart的单位默认是px的(好像也不支持vh、vw),1920×1080的设计稿如果需要适配4K屏幕的话,图像的x轴y轴字体会非常小,所以echart字体大小的适配我是单独去做的。
适配的方式很简单,就是获取缩放比scale之后,然后修改原来的字体大小,比如4K屏幕(3840×2160)相较于1920×1080,scale就是2,原来字体14px的地方修改为28px。
//挂载的时候添加监听事件
window.addEventListener('resize', this.updateScale)
//获取缩放比 传递给所有子组件
updateScale() {
this.scale = window.innerWidth / 1920
this.dialogHeight = this.scale * 30
},
yAxis: {
type: 'value',
minInterval: 1,
axisLabel: {
// 坐标轴字体颜色
textStyle: {
color: '#9eaaba',
fontSize: getFontSize(14, this.scale)
}
},
axisLine: {
show: false
},
axisTick: {
// y轴刻度线
show: false
},
splitLine: {
show: false
}
},
getFontSize是一个很简单的公用方法
export function getFontSize(size, scale) {
return size * scale
}
开机自启动
如果需要展示在电视机上,老板不想要浏览器打开,或者做了看板但是不适配安卓系统,或者需要将大屏项目设置为开机自启动的应用,可以选择把项目用hbuilder打包成apk文件,这样很多问题都能迎刃而解。 (也可以写个脚本,每次开机就启动浏览器,打开大屏。
尽管大屏适配的过程可能比较繁琐,但通过合理的方案组合和架构设计,我们不仅能确保信息在不同设备上的可读性和一致性,还能提升用户体验。希望本文能为各位的大屏适配工作提供一些实用的思路和参考。欢迎讨论。