前端大屏开发3种主流适配方案总结
作者:zqwang888
摘要
目前主流三种:
1.vw vh方案:
- 实现方式:按照设计稿的尺寸,将
px
按比例计算转为vw
和vh
- 优点:1.可以动态计算图表的宽高,字体等,灵活性较高 2.当屏幕比例跟 ui 稿不一致时,不会出现两边留白情况
- 缺点:每个图表都需要单独做字体、间距、位移的适配,比较麻烦
2.scale方案:
- 实现方式:通过
scale
属性,根据屏幕大小,对图表进行整体的等比缩放 - 优点:1.代码量少,适配简单 2.一次处理后不需要在各个图表中再去单独适配
- 缺点:1.因为是根据 ui 稿等比缩放,当大屏跟 ui 稿的比例不一样时,会出现周边留白情况 2.当缩放比例过大时候,字体会有一点点模糊,就一点点 3.当缩放比例过大时候,事件热区会偏移。
3.rem + vw vh方案:
- 实现方式:1.获得 rem 的基准值 2.动态的计算
html根元素的font-size
3.图表中通过 vw vh 动态计算字体、间距、位移等 - 优点:布局的自适应代码量少,适配简单
- 缺点:1.因为是根据 ui 稿等比缩放,当大屏跟 ui 稿的比例不一样时,会出现周边留白情况 2.图表需要单个做字体、间距、位移的适配
方案一、vw vh
说明:
1.当屏幕尺寸比例大于设计稿,页面有被压缩的感觉
2.当屏幕尺寸比例小于设计稿,页面有被放大的感觉
按照设计稿的尺寸,将px
按比例计算转为vw
和vh
,转换公式如下
假设设计稿尺寸为 1920*1080(做之前一定问清楚 ui 设计稿的尺寸) 即: 网页宽度=1920px 网页高度=1080px 网页宽度=100vw 网页宽度=100vh 所以,在 1920px*1080px 的屏幕分辨率下 1920px = 100vw 1080px = 100vh 这样一来,以一个宽 300px 和 200px 的 div 来说,其所占的宽高,以 vw 和 vh 为单位,计算方式如下: vwDiv = (300px / 1920px) * 100vw vhDiv = (200px / 1080px) * 100vh 所以,就在 1920*1080 的屏幕分辨率下,计算出了单个 div 的宽高 当屏幕放大或者缩小时,div 还是以 vw 和 vh 作为宽高的,就会自动适应不同分辨率的屏幕
1. css 方案 - sass
util.scss
// 使用 scss 的 math 函数,https://sass-lang.com/documentation/breaking-changes/slash-div @use "sass:math"; // 默认设计稿的宽度 $designWidth: 1920; // 默认设计稿的高度 $designHeight: 1080; // px 转为 vw 的函数 @function vw($px) { @return math.div($px, $designWidth) * 100vw; } // px 转为 vh 的函数 @function vh($px) { @return math.div($px, $designHeight) * 100vh; }
只需在vue.config.js
里配置一下utils.scss
的路径,就可以全局使用了
vue.config.js
const path = require("path"); function resolve(dir) { return path.join(__dirname, dir); } module.exports = { publicPath: "", configureWebpack: { name: "app name", resolve: { alias: { "@": resolve("src"), }, }, }, css: { // 全局配置 utils.scs,详细配置参考 vue-cli 官网 loaderOptions: { sass: { prependData: `@import "@/styles/utils.scss";`, }, }, }, };
在 vue 中使用
<template> <div class="box"> </div> </template> <script> export default{ name: "Box", } </script> <style lang="scss" scoped="scoped"> /* 直接使用 vw 和 vh 函数,将像素值传进去,得到的就是具体的 vw vh 单位 */ .box{ width: vw(300); height: vh(100); font-size: vh(16); background-color: black; margin-left: vw(10); margin-top: vh(10); border: vh(2) solid red; } </style>
2. 定义 js 样式处理函数
// 定义设计稿的宽高 const designWidth = 1920 const designHeight = 1080 // px转vw export const px2vw = (_px) => { return (_px * 100) / designWidth + 'vw' } export const px2vh = (_px) => { return (_px * 100.0) / designHeight + 'vh'; }; export const px2font = (_px) => { return (_px * 100.0) / designWidth + 'vw'; };
屏幕变化后,图表自动调整
封装自定义指令
// directive.js import * as ECharts from "echarts"; import elementResizeDetectorMaker from "element-resize-detector"; import Vue from "vue"; const HANDLER = "_vue_resize_handler"; function bind(el, binding) { el[HANDLER] = binding.value ? binding.value : () => { let chart = ECharts.getInstanceByDom(el); if (!chart) { return; } chart.resize(); }; // 监听绑定的div大小变化,更新 echarts 大小 elementResizeDetectorMaker().listenTo(el, el[HANDLER]); } function unbind(el) { // window.removeEventListener("resize", el[HANDLER]); elementResizeDetectorMaker().removeListener(el, el[HANDLER]); delete el[HANDLER]; } // 自定义指令:v-chart-resize 示例:v-chart-resize="fn" Vue.directive("chart-resize", { bind, unbind });
图表之间的文字、间距、位移等尺寸自适应
- 其原理是计算出当前屏幕宽度和默认设计宽度的比值,将原始的尺寸乘以该值,写个工具函数
方案二:scale
通过 css 的 scale 属性,根据屏幕大小,对图表进行整体的等比缩放,从而达到自适应效果
1.当屏幕尺寸比例大于设计稿,页面左右留白,上下占满并居中,显示比例保持 16:9
2.当屏幕尺寸比例小于设计稿,页面上下留白,左右占满并上下居中,显示比例保持 16:9
html 部分
<div className="screen-wrapper"> <div className="screen" id="screen"> </div> </div>
js 部分
<script> export default { mounted() { // 初始化自适应 --在刚显示时候开始适配一次 handleScreenAuto(); // 绑定自适应函数 ---防止浏览器栏变化后不再适配 window.onresize = () => handleScreenAuto(); }, destroyed() { window.onresize = null; }, methods: { handleScreenAuto() { const designDraftWidth = 1920; //设计稿的宽度 const designDraftHeight = 960; //设计稿的高度 // 根据屏幕的变化适配的比例 const scale = document.documentElement.clientWidth / document.documentElement.clientHeight < designDraftWidth / designDraftWidth ? document.documentElement.clientWidth / designDraftWidth : document.documentElement.clientHeight / designDraftHeight; // 缩放比例 document.querySelector('#screen').style.transform = `scale(${scale}) translate(-50%, -50%)`; } } } </script>
CSS部分
/* 除了设计稿的宽高是根据您自己的设计稿决定以外,其他复制粘贴就完事 */ .screen-root { height: 100%; width: 100%; .screen { display: inline-block; width: 1920px; //设计稿的宽度 height: 960px; //设计稿的高度 transform-origin: 0 0; position: absolute; left: 50%; top: 50%; } }
方案三:rem + vw wh
1.当屏幕尺寸比例大于设计稿,页面左右留白,上下占满并居中,显示比例保持 16:9
2.当屏幕尺寸比例小于设计稿,页面上下留白,左右占满并上下居中,显示比例保持 16:9
关于 rem
rem(font size of the root element)
,是 css3 中新增的一个大小单位,即相对于根元素 font-size 值的大小。
自适应思路动态的计算出页面的 fontsize 从而改变 rem 的大小。
- 将屏幕分为10份,以1920 * 1080为例子,先计算rem的基准值:1920/10 = 192
- 把所有元素的长,宽,位置,字体大小等原来的px转成rem
- 网页加载后,用js计算当前浏览器的宽度,并设置html的font-size为(当前窗口宽度 / 10) ,这样的话 10rem 就刚好等于浏览器窗口的宽度,也就可以保证 100% 宽度,等比例缩放设计稿的页面了。
rem + vw vh 方案要解决三件事
- 获取rem的基准值
- 页面内写一段js,动态计算html根元素的font-size
- 屏幕变化后,图表自动调整和图表字体、间距、位移等的自适应
1、获得 rem 的基准值
- 首先安装
postcss-px-to-rem
这个包 - 在项目根目录新建
.postcssrc.js
配置文件
module.exports = { plugins: { autoprefixer: {}, "postcss-px-to-rem": { unitToConvert: 'px', // (String) 要转换的单位,默认是 px。 widthOfDesignLayout: 1920, // (Number) 设计布局的宽度。对于pc仪表盘,一般是 1920. unitPrecision: 3, // (Number) 允许 rem 单位增长到的十进制数字. selectorBlackList: ['.ignore', '.hairlines'], // (Array) 要忽略并保留为 px 的选择器. minPixelValue: 1, // (Number) 设置要替换的最小像素值. mediaQuery: false // (Boolean) 允许在媒体查询中转换 px. } } }
配置完成后,页面内的 px 就会被转换成 rem 了
2、动态的计算html根元素的font-size
在工具函数文件中新建一个 rem.js 文件,用于动态计算 font-size
(function init(screenRatioByDesign = 16 / 9) { let docEle = document.documentElement function setHtmlFonstSize() { var screenRatio = docEle.clientWidth / docEle.clientHeight; var fontSize = ( screenRatio > screenRatioByDesign ? (screenRatioByDesign / screenRatio) : 1 ) * docEle.clientWidth / 10; docEle.style.fontSize = fontSize.toFixed(3) + "px"; console.log(docEle.style.fonSize); } setHtmlFontSize() window.addEventListener('resize', setHtmlFontSize) })
在入口文件 main.js 中引入 rem.js 文件
import './utils/rem.js';
3、屏幕变化,图表自适应
屏幕变化后,图表自动调整字体、间距、位移等,此处参考上面 vw vh 的实现方式即可
总结
到此这篇关于前端大屏开发3种主流适配方案总结的文章就介绍到这了,更多相关前端大屏适配方案内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!