前端大屏開發(fā)3種主流適配方案總結(jié)
摘要
目前主流三種:
1.vw vh方案:
- 實(shí)現(xiàn)方式:按照設(shè)計(jì)稿的尺寸,將
px按比例計(jì)算轉(zhuǎn)為vw和vh - 優(yōu)點(diǎn):1.可以動(dòng)態(tài)計(jì)算圖表的寬高,字體等,靈活性較高 2.當(dāng)屏幕比例跟 ui 稿不一致時(shí),不會(huì)出現(xiàn)兩邊留白情況
- 缺點(diǎn):每個(gè)圖表都需要單獨(dú)做字體、間距、位移的適配,比較麻煩
2.scale方案:
- 實(shí)現(xiàn)方式:通過
scale屬性,根據(jù)屏幕大小,對(duì)圖表進(jìn)行整體的等比縮放 - 優(yōu)點(diǎn):1.代碼量少,適配簡(jiǎn)單 2.一次處理后不需要在各個(gè)圖表中再去單獨(dú)適配
- 缺點(diǎn):1.因?yàn)槭歉鶕?jù) ui 稿等比縮放,當(dāng)大屏跟 ui 稿的比例不一樣時(shí),會(huì)出現(xiàn)周邊留白情況 2.當(dāng)縮放比例過大時(shí)候,字體會(huì)有一點(diǎn)點(diǎn)模糊,就一點(diǎn)點(diǎn) 3.當(dāng)縮放比例過大時(shí)候,事件熱區(qū)會(huì)偏移。
3.rem + vw vh方案:
- 實(shí)現(xiàn)方式:1.獲得 rem 的基準(zhǔn)值 2.動(dòng)態(tài)的計(jì)算
html根元素的font-size3.圖表中通過 vw vh 動(dòng)態(tài)計(jì)算字體、間距、位移等 - 優(yōu)點(diǎn):布局的自適應(yīng)代碼量少,適配簡(jiǎn)單
- 缺點(diǎn):1.因?yàn)槭歉鶕?jù) ui 稿等比縮放,當(dāng)大屏跟 ui 稿的比例不一樣時(shí),會(huì)出現(xiàn)周邊留白情況 2.圖表需要單個(gè)做字體、間距、位移的適配
方案一、vw vh
說明:
1.當(dāng)屏幕尺寸比例大于設(shè)計(jì)稿,頁(yè)面有被壓縮的感覺
2.當(dāng)屏幕尺寸比例小于設(shè)計(jì)稿,頁(yè)面有被放大的感覺
按照設(shè)計(jì)稿的尺寸,將px按比例計(jì)算轉(zhuǎn)為vw和vh,轉(zhuǎn)換公式如下
假設(shè)設(shè)計(jì)稿尺寸為 1920*1080(做之前一定問清楚 ui 設(shè)計(jì)稿的尺寸) 即: 網(wǎng)頁(yè)寬度=1920px 網(wǎng)頁(yè)高度=1080px 網(wǎng)頁(yè)寬度=100vw 網(wǎng)頁(yè)寬度=100vh 所以,在 1920px*1080px 的屏幕分辨率下 1920px = 100vw 1080px = 100vh 這樣一來(lái),以一個(gè)寬 300px 和 200px 的 div 來(lái)說,其所占的寬高,以 vw 和 vh 為單位,計(jì)算方式如下: vwDiv = (300px / 1920px) * 100vw vhDiv = (200px / 1080px) * 100vh 所以,就在 1920*1080 的屏幕分辨率下,計(jì)算出了單個(gè) div 的寬高 當(dāng)屏幕放大或者縮小時(shí),div 還是以 vw 和 vh 作為寬高的,就會(huì)自動(dòng)適應(yīng)不同分辨率的屏幕
1. css 方案 - sass
util.scss
// 使用 scss 的 math 函數(shù),https://sass-lang.com/documentation/breaking-changes/slash-div
@use "sass:math";
// 默認(rèn)設(shè)計(jì)稿的寬度
$designWidth: 1920;
// 默認(rèn)設(shè)計(jì)稿的高度
$designHeight: 1080;
// px 轉(zhuǎn)為 vw 的函數(shù)
@function vw($px) {
@return math.div($px, $designWidth) * 100vw;
}
// px 轉(zhuǎn)為 vh 的函數(shù)
@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,詳細(xì)配置參考 vue-cli 官網(wǎng)
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 函數(shù),將像素值傳進(jìn)去,得到的就是具體的 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 樣式處理函數(shù)
// 定義設(shè)計(jì)稿的寬高
const designWidth = 1920
const designHeight = 1080
// px轉(zhuǎn)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'; };
屏幕變化后,圖表自動(dòng)調(diào)整
封裝自定義指令
// 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();
};
// 監(jiān)聽綁定的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 });
圖表之間的文字、間距、位移等尺寸自適應(yīng)
- 其原理是計(jì)算出當(dāng)前屏幕寬度和默認(rèn)設(shè)計(jì)寬度的比值,將原始的尺寸乘以該值,寫個(gè)工具函數(shù)
方案二:scale
通過 css 的 scale 屬性,根據(jù)屏幕大小,對(duì)圖表進(jìn)行整體的等比縮放,從而達(dá)到自適應(yīng)效果
1.當(dāng)屏幕尺寸比例大于設(shè)計(jì)稿,頁(yè)面左右留白,上下占滿并居中,顯示比例保持 16:9
2.當(dāng)屏幕尺寸比例小于設(shè)計(jì)稿,頁(yè)面上下留白,左右占滿并上下居中,顯示比例保持 16:9
html 部分
<div className="screen-wrapper">
<div className="screen" id="screen">
</div>
</div>js 部分
<script>
export default {
mounted() {
// 初始化自適應(yīng) --在剛顯示時(shí)候開始適配一次
handleScreenAuto();
// 綁定自適應(yīng)函數(shù) ---防止瀏覽器欄變化后不再適配
window.onresize = () => handleScreenAuto();
},
destroyed() {
window.onresize = null;
},
methods: {
handleScreenAuto() {
const designDraftWidth = 1920; //設(shè)計(jì)稿的寬度
const designDraftHeight = 960; //設(shè)計(jì)稿的高度
// 根據(jù)屏幕的變化適配的比例
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部分
/*
除了設(shè)計(jì)稿的寬高是根據(jù)您自己的設(shè)計(jì)稿決定以外,其他復(fù)制粘貼就完事
*/
.screen-root {
height: 100%;
width: 100%;
.screen {
display: inline-block;
width: 1920px; //設(shè)計(jì)稿的寬度
height: 960px; //設(shè)計(jì)稿的高度
transform-origin: 0 0;
position: absolute;
left: 50%;
top: 50%;
}
}
方案三:rem + vw wh
1.當(dāng)屏幕尺寸比例大于設(shè)計(jì)稿,頁(yè)面左右留白,上下占滿并居中,顯示比例保持 16:9
2.當(dāng)屏幕尺寸比例小于設(shè)計(jì)稿,頁(yè)面上下留白,左右占滿并上下居中,顯示比例保持 16:9
關(guān)于 rem
rem(font size of the root element),是 css3 中新增的一個(gè)大小單位,即相對(duì)于根元素 font-size 值的大小。
自適應(yīng)思路動(dòng)態(tài)的計(jì)算出頁(yè)面的 fontsize 從而改變 rem 的大小。
- 將屏幕分為10份,以1920 * 1080為例子,先計(jì)算rem的基準(zhǔn)值:1920/10 = 192
- 把所有元素的長(zhǎng),寬,位置,字體大小等原來(lái)的px轉(zhuǎn)成rem
- 網(wǎng)頁(yè)加載后,用js計(jì)算當(dāng)前瀏覽器的寬度,并設(shè)置html的font-size為(當(dāng)前窗口寬度 / 10) ,這樣的話 10rem 就剛好等于瀏覽器窗口的寬度,也就可以保證 100% 寬度,等比例縮放設(shè)計(jì)稿的頁(yè)面了。
rem + vw vh 方案要解決三件事
- 獲取rem的基準(zhǔn)值
- 頁(yè)面內(nèi)寫一段js,動(dòng)態(tài)計(jì)算html根元素的font-size
- 屏幕變化后,圖表自動(dòng)調(diào)整和圖表字體、間距、位移等的自適應(yīng)
1、獲得 rem 的基準(zhǔn)值
- 首先安裝
postcss-px-to-rem這個(gè)包 - 在項(xiàng)目根目錄新建
.postcssrc.js配置文件
module.exports = {
plugins: {
autoprefixer: {},
"postcss-px-to-rem": {
unitToConvert: 'px', // (String) 要轉(zhuǎn)換的單位,默認(rèn)是 px。
widthOfDesignLayout: 1920, // (Number) 設(shè)計(jì)布局的寬度。對(duì)于pc儀表盤,一般是 1920.
unitPrecision: 3, // (Number) 允許 rem 單位增長(zhǎng)到的十進(jìn)制數(shù)字.
selectorBlackList: ['.ignore', '.hairlines'], // (Array) 要忽略并保留為 px 的選擇器.
minPixelValue: 1, // (Number) 設(shè)置要替換的最小像素值.
mediaQuery: false // (Boolean) 允許在媒體查詢中轉(zhuǎn)換 px.
}
}
}配置完成后,頁(yè)面內(nèi)的 px 就會(huì)被轉(zhuǎn)換成 rem 了
2、動(dòng)態(tài)的計(jì)算html根元素的font-size
在工具函數(shù)文件中新建一個(gè) rem.js 文件,用于動(dòng)態(tài)計(jì)算 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、屏幕變化,圖表自適應(yīng)
屏幕變化后,圖表自動(dòng)調(diào)整字體、間距、位移等,此處參考上面 vw vh 的實(shí)現(xiàn)方式即可
總結(jié)
到此這篇關(guān)于前端大屏開發(fā)3種主流適配方案總結(jié)的文章就介紹到這了,更多相關(guān)前端大屏適配方案內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
躲避這些會(huì)改變?cè)瓟?shù)組JavaScript數(shù)組方法讓開發(fā)流暢無(wú)阻
JavaScript中有些數(shù)組的操作方法并不符合我們預(yù)期,容易導(dǎo)致想象不到的結(jié)果,因此,為避免這種情況的發(fā)生,本文將介紹哪些原生數(shù)組方法能改變?cè)瓟?shù)組以及我對(duì)于如何更好地使用數(shù)組方法的建議2023-05-05
uniapp微信小程序無(wú)法使用本地靜態(tài)資源圖片(背景圖在真機(jī)不顯示)的解決方法
寫微信小程序的時(shí)候,難免會(huì)為了趕進(jìn)度而直接使用本地的圖片,在模擬器上的時(shí)候可以正確顯示圖片,但是到手機(jī)上就無(wú)法顯示圖片了,下面這篇文章主要給大家介紹了關(guān)于uniapp微信小程序無(wú)法使用本地靜態(tài)資源圖片(背景圖在真機(jī)不顯示)的方法,需要的朋友可以參考下2022-12-12
使用mock.js隨機(jī)數(shù)據(jù)和使用express輸出json接口的實(shí)現(xiàn)方法
這篇文章主要介紹了使用mock.js隨機(jī)數(shù)據(jù)和使用express輸出json接口的實(shí)現(xiàn)方法,需要的朋友可以參考下2018-01-01

