大屏適配方案
阿新 • • 發佈:2022-12-07
一、問題引入:
視覺化資料大屏需要適配各種大屏尺寸
1080P:1920*1080
2K:2560*1440 左右
4K:3840*2160 左右
8K:7680*4320 左右
二、適配方案分析
- 如果想簡單,客戶能同意留白,選用
scale
即可 - 如果需要相容不同比例的大屏,並且想在不同比例中都有比較好的效果,圖表佔滿螢幕,類似於移動端的響應式,可以採用 vm vh 的方案
- 至於 rem,個人覺得就是 scale 和 vm vh 的綜合,最終的效果跟
scale
差不多
三、方案一
實現思路
按照設計稿的尺寸,將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 作為寬高的,就會自動適應不同解析度的螢幕
相關程式碼如下:
使用less方式:
1.安裝外掛:
npm i style-resources-loader --save-dev
2.新建utils.less檔案:
@charset "utf-8"; // 預設設計稿的寬度 @designWidth: 1920; // 預設設計稿的高度 @designHeight: 1080; .px2vw(@name, @px) { @{name}: (@px / @designWidth) * 100vw; } .px2vh(@name, @px) { @{name}: (@px / @designHeight) * 100vh; } .px2font(@px) { font-size: (@px / @designWidth) * 100vw; } .px2vwCalc(@name, @px, @scale) { @{name}: calc(@scale - (@px / @designWidth) * 100vw); } .px2vhCalc(@name, @px, @scale) { @{name}: calc(@scale - (@px / @designHeight) * 100vh); } // padding margin簡寫 .px2pm(@name, @pxheight, @pxwidth) { @{name}: ((@pxheight / @designHeight) * 100vh) ((@pxwidth / @designWidth) * 100vw); }
3.路徑配置
在vue.config.js
裡配置一下utils.less
module.exports = { ... // 全域性配置utils.less pluginOptions: { "style-resources-loader": { preProcessor: "less", patterns: [ path.resolve(__dirname, "./src/assets/css/utils.less") ] } } }
網上查資料亦可使用
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.scss loaderOptions: { less: { additionalData: `@import "@/styles/utils.less";`, }, }, }, };
4.在vue檔案中使用
.el-dialog__header { // padding: 24px; .px2vw(padding, 24); // padding-bottom: 20px; .px2vw(padding-bottom, 20); .el-dialog__headerbtn { // top: 20px; .px2vh(top, 20); // right: 20px; .px2vw(right, 20); // font-size: 16px; .px2font(16); } }
說明:如果報錯 .px2vw 為undefined說明全域性配置有問題,由於cli版本不同,安裝下面外掛即可解決
npm i vue-cli-plugin-style-resources-loader --save-dev
5.定義js樣式處理函式 util.js
// 定義設計稿的寬高 const designWidth = 1920; const designHeight = 1080; // px轉vw export const px2vw = (_px) => { return (_px * 100.0) / designWidth + 'vw'; }; export const px2vh = (_px) => { return (_px * 100.0) / designHeight + 'vh'; }; export const px2font = (_px) => { return (_px * 100.0) / designWidth + 'vw'; };
全域性寫入vue原型
import { px2vw, px2vh, px2font } from './assets/utils' Vue.prototype.$px2vw = px2vw Vue.prototype.$px2vh = px2vh Vue.prototype.$px2font = px2font
頁面或者js中使用
<el-dialog :width="$px2vw(800)"></el-dialog>
6.圖表字型、間距、位移等尺寸自適應
編寫 dataUtil.js 工具函式
// Echarts圖表字型、間距自適應 export const fitChartSize = (size,defalteWidth = 1920) => { let clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth; if (!clientWidth) return size; let scale = (clientWidth / defalteWidth); return Number((size*scale).toFixed(3)); }
將函式掛載到原型上
import {fitChartSize} from '@src/utils/dataUtil.js'
Vue.prototype.fitChartSize = fitChartSize;
圖表配置options中使用
legend: { // top: 15, top: _this.fitChartSize(15), // itemWidth: 8, itemWidth: _this.fitChartSize(8), // itemHeight: 8, itemHeight: _this.fitChartSize(8), textStyle: { fontFamily: 'AlibabaPuHuiTi-Regular', // fontSize: 14, fontSize: _this.fitChartSize(14), color: '#FFFFFF', fontWeight: 400 } }, grid: { // left: 80, left: _this.fitChartSize(80), // right: 170, right: _this.fitChartSize(170), // bottom: 30, bottom: _this.fitChartSize(30), // top: 50 top: _this.fitChartSize(50) },
使用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配置
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";`, }, }, }, };
如若報錯undefined,需要安裝sass相關外掛,具體自行查閱資料