总结一下我常用的数据大屏自适应方法
目录
- 1、通过css缩放方案: 利用transform:scale 进行适配
- 2、采用rem布局, 根据屏幕分辨率大小不同,调整根元素html的font-size, 从而达到每个元素宽高自动变化,适配不同屏幕
- 2.1、先下载postcss-pxtorem
- 2.2、在vite.config.ts配置
- 2.3、在src/utils下创建flexible.js文件(lib-flexible插件建议放到本地)
- 2.4、在main.js中引入flexible.js
- 2.5、注意事项
1、通过css缩放方案: 利用transform:scale 进行适配
我一般使用 v-scale-screen 插件
主要用于同比例缩放,例如16:9(1k,2k,4k)
vue2版本(npm官网):https://www.npmjs.com/package/vue2-scale-box
vue3版本(npm官网):https://www.npmjs.com/package/vue3-scale-box
yarn add vue3-scale-box<template><ScaleBox:width="1920":height="1080"bgc="transparent":delay="100":isFlat="false"><div class="ec-demo" id="ec-demo"></div></ScaleBox>
</template>
<script setup>
import ScaleBox from "vue3-scale-box";
</script>
2、采用rem布局, 根据屏幕分辨率大小不同,调整根元素html的font-size, 从而达到每个元素宽高自动变化,适配不同屏幕
我一般使用 postcss-pxtorem + lib-flexible 插件
主要用于多个不同比例缩放,例如16:9(1k,2k,4k),21:9或其他比例
适配的方法总体分为两步:
- px转换成rem
- rem根据屏幕大小重置基数改变大小
2.1、先下载postcss-pxtorem
yarn add postcss-pxtorem "postcss-pxtorem": "^6.0.0",
2.2、在vite.config.ts配置
import postcssPxtoRem from "postcss-pxtorem";css: {postcss: {plugins: [postcssPxtoRem({rootValue: 192, // 按照自己的设计稿修改 1920/10unitPrecision: 5, // 保留到5位小数selectorBlackList: ["ignore"], // 忽略转换正则匹配项propList: ["*", "!border"],replace: true,mediaQuery: false, // 媒体查询( @media screen 之类的)中不生效minPixelValue: 1, //可以选择px小于1的不会被转换}),],},
},
2.3、在src/utils下创建flexible.js文件(lib-flexible插件建议放到本地)
因为我要适配不同比例的大屏,我把lib-flexible插件放在了本地(方便修改)
可以在 refreshRem() 方法中对不同分辨率进行设置
(function (win, lib) {var doc = win.document;var docEl = doc.documentElement;var metaEl = doc.querySelector('meta[name="viewport"]');var flexibleEl = doc.querySelector('meta[name="flexible"]');var dpr = 0;var scale = 0;var tid;var flexible = lib.flexible || (lib.flexible = {});if (metaEl) {console.warn("将根据已有的meta标签来设置缩放比例");var match = metaEl.getAttribute("content").match(/initial\-scale=([\d\.]+)/);if (match) {scale = parseFloat(match[1]);dpr = parseInt(1 / scale);}} else if (flexibleEl) {var content = flexibleEl.getAttribute("content");if (content) {var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);if (initialDpr) {dpr = parseFloat(initialDpr[1]);scale = parseFloat((1 / dpr).toFixed(2));}if (maximumDpr) {dpr = parseFloat(maximumDpr[1]);scale = parseFloat((1 / dpr).toFixed(2));}}}if (!dpr && !scale) {var isAndroid = win.navigator.appVersion.match(/android/gi);var isIPhone = win.navigator.appVersion.match(/iphone/gi);var devicePixelRatio = win.devicePixelRatio;if (isIPhone || isAndroid) {// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {dpr = 3;} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {dpr = 2;} else {dpr = 1;}} else {// 其他设备下,仍旧使用1倍的方案dpr = devicePixelRatio;}scale = 1 / dpr;// scale = 1 * dpr;}docEl.setAttribute("data-dpr", dpr);if (!metaEl) {metaEl = doc.createElement("meta");metaEl.setAttribute("name", "viewport");metaEl.setAttribute("content","initial-scale=" +scale +", maximum-scale=" +scale +", minimum-scale=" +scale +", user-scalable=no");if (docEl.firstElementChild) {docEl.firstElementChild.appendChild(metaEl);} else {var wrap = doc.createElement("div");wrap.appendChild(metaEl);doc.write(wrap.innerHTML);}}function refreshRem() {var width = docEl.getBoundingClientRect().width;var height = docEl.getBoundingClientRect().height;if (width / dpr < 1600) {width = 1920 * dpr;}var rem = (width * dpr) / 10;docEl.style.fontSize = rem + "px";flexible.rem = win.rem = rem;// if(width>3040&&width<3640){// docEl.style.fontSize = 1 + "px";// flexible.rem = 1 + "px";// }}win.addEventListener("resize",function () {refreshRem();},false);win.addEventListener("pageshow",function (e) {if (e.persisted) {refreshRem();}},false);if (doc.readyState === "complete") {doc.body.style.fontSize = 12 * dpr + "px";} else {doc.addEventListener("DOMContentLoaded",function () {doc.body.style.fontSize = 12 * dpr + "px";},false);}refreshRem();flexible.dpr = win.dpr = dpr;flexible.refreshRem = refreshRem;flexible.rem2px = function (d) {var val = parseFloat(d) * this.rem;if (typeof d === "string" && d.match(/rem$/)) {val += "px";}return val;};flexible.px2rem = function (d) {var val = parseFloat(d) / this.rem;if (typeof d === "string" && d.match(/px$/)) {val += "rem";}return val;};
})(window, window["lib"] || (window["lib"] = {}));
2.4、在main.js中引入flexible.js
//px转rem
// 使用下面@ts-ignore表示忽略ts类型检测,否则下面代码打包时会报错
import '@/utils/flexible.js'
2.5、注意事项
1、 框架组件和标签中直接定义的 width和height进行不了转换, 例如img标签
2、 大多框架只适配1920*1080的,其他比例,框架组件可能会变形,需要单独设置,可以在全局css文件进行修改。