Vue3基于?rem?比例縮放方案示例詳解
Vue3基于 rem 比例縮放方案
本縮放方案置于hooks中即可。于App.vue中引入并調(diào)用。會(huì)在頁(yè)面DOM結(jié)構(gòu)最外層增加響應(yīng)式的font-size屬性樣式更改。
主要包含了以下內(nèi)容
1.接口和類型定義:
DesignParms
:設(shè)計(jì)稿參數(shù)的接口定義,包括寬度、高度和字體大小等信息。UseRemOption
:使用 rem 的配置參數(shù)的接口定義,包括延遲觸發(fā)時(shí)間。Designs
:設(shè)計(jì)稿集合的類型定義,是一個(gè)由DesignParms
構(gòu)成的數(shù)組。
2.默認(rèn)設(shè)計(jì)稿方案和配置參數(shù):
DEFAULT_DESIGNS
:默認(rèn)的設(shè)計(jì)稿方案,包含多個(gè)不同分辨率下的設(shè)計(jì)稿信息。DEFAULT_OPTION
:默認(rèn)的配置參數(shù),包括延遲觸發(fā)時(shí)間。
3.useEqualScaling
函數(shù):
- 該函數(shù)接受設(shè)計(jì)稿集合和配置參數(shù)作為參數(shù),并返回縮放信息和方法。
- 函數(shù)內(nèi)部根據(jù)窗口大小和設(shè)計(jì)稿信息計(jì)算最合適的設(shè)計(jì)稿作為參考設(shè)計(jì)稿。
- 在頁(yè)面加載和窗口大小改變時(shí),會(huì)觸發(fā)
setHtmlFontSize
方法進(jìn)行根節(jié)點(diǎn)字體大小的計(jì)算和設(shè)置。 - 函數(shù)返回設(shè)計(jì)稿集合、參考設(shè)計(jì)稿和設(shè)置根節(jié)點(diǎn)字體大小的方法
/** * 基于rem 的比例縮放方案 * @author wangguanjie 2022.06.09 */ import { onBeforeUnmount, onMounted, ref } from "vue"; /** * 設(shè)計(jì)稿參數(shù) * @example 1920 * 1080 下 {width: 1920, height: 1080, fontSize: 16, ...} * @example 1680 * 1050 下 {width: 1680, height: 1050, fontSize: 14, ...} * @example 1280 * 800 下 {width: 1280, height: 800, fontSize: 12, ...} */ export interface DesignParms { width: number; height: number; fontSize: number; } export interface UseRemOption { delay?: number; } export type Designs = DesignParms[]; /** * 默認(rèn)設(shè)計(jì)稿方案 */ const DEFAULT_DESIGNS: Designs = [ { width: 800, height: 600, fontSize: 12 }, { width: 1024, height: 500, fontSize: 12 }, { width: 1024, height: 768, fontSize: 12 }, // HD { width: 1280, height: 800, fontSize: 12 }, // WXGA { width: 1280, height: 854, fontSize: 12 }, { width: 1280, height: 1024, fontSize: 12 }, { width: 1366, height: 768, fontSize: 14 }, { width: 1440, height: 900, fontSize: 14 }, { width: 1440, height: 1050, fontSize: 14 }, { width: 1600, height: 1024, fontSize: 14 }, { width: 1600, height: 1200, fontSize: 14 }, // UXGA { width: 1680, height: 1050, fontSize: 14 }, { width: 1920, height: 937, fontSize: 16 }, // FHD { width: 1920, height: 1080, fontSize: 16 }, // FHD { width: 1920, height: 1200, fontSize: 16 }, // WUXGA { width: 2048, height: 1080, fontSize: 18 }, { width: 2048, height: 1536, fontSize: 18 }, // QXGA { width: 2560, height: 1080, fontSize: 18 }, { width: 2560, height: 1440, fontSize: 18 }, // QHD { width: 2560, height: 1600, fontSize: 18 }, // WQXGA { width: 3440, height: 1440, fontSize: 18 }, { width: 3840, height: 1080, fontSize: 18 }, { width: 3840, height: 2160, fontSize: 18 }, // UHD { width: 4096, height: 2160, fontSize: 18 }, // 4K Ultra HD ]; /** * 默認(rèn)配置參數(shù) */ const DEFAULT_OPTION: Required<UseRemOption> = { // 觸發(fā)延時(shí),默認(rèn)2022 delay: 0, }; /** * 等比縮放方案 * @author wangguanjie 2022.06.09 * @description 該方案支持多設(shè)計(jì)稿 * @param designs 設(shè)計(jì)稿集合 * @param option 縮放配置參數(shù) * @returns 縮放信息、方法 */ export const useEqualScaling = function ( designs: Designs = DEFAULT_DESIGNS, option: UseRemOption = DEFAULT_OPTION ) { let timer: number | undefined; // 確保有設(shè)計(jì)稿可參考 designs = designs.length ? designs : DEFAULT_DESIGNS; // 將設(shè)計(jì)搞進(jìn)行升序排序,供后續(xù)快速排查 designs .filter((d) => d.width > 1 && d.height > 1) .sort((d1, d2) => { if (d1.width === d2.width) { return d1.height - d2.height; } return d1.width - d2.width; }); // 降序排序的設(shè)計(jì)稿 const descendingDesigns = designs.map((d) => d).reverse(); // 瀏覽器適配所參考的設(shè)計(jì)稿 const referDesign = ref(designs[0]); /** * 根據(jù)多份設(shè)計(jì)搞自適應(yīng)根節(jié)點(diǎn)字號(hào) */ const setHtmlFontSize = () => { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { const { clientWidth: docW, clientHeight: docH } = document.documentElement; // 匹配最佳設(shè)計(jì)稿 const hasNewReferDesignIndex = designs.findIndex( (d) => d.width >= docW && d.height >= docH ); if (hasNewReferDesignIndex !== -1) { referDesign.value = designs[hasNewReferDesignIndex]; } else { // 優(yōu)先篩選寬度符合的設(shè)計(jì)搞 const accordWidthDesigns = descendingDesigns.filter( (d) => d.width <= docW ); // 再確認(rèn)最接近設(shè)計(jì)稿高度的設(shè)計(jì)稿 const designsHeightList = accordWidthDesigns.map((d) => d.height); const useDesignIndex = designsHeightList .map((designH) => Math.abs(docH - designH)) .findIndex( (designH) => designH === Math.min(...designsHeightList.map((dh) => Math.abs(docH - dh))) ); referDesign.value = accordWidthDesigns[useDesignIndex]; } // 依據(jù)所參考的設(shè)計(jì)稿變更根節(jié)點(diǎn)字號(hào) const documentRatio = docW / docH; const { width: designW, height: designH, fontSize: designFontSize, } = referDesign.value; const designRatio = designW / designH; const htmlFontSize = documentRatio < designRatio ? (docW / designW) * designFontSize : (docH / designH) * designFontSize; const html = document.querySelector("html"); if (html) { html.style.fontSize = `${htmlFontSize}px`; } }, option.delay ?? DEFAULT_OPTION.delay); }; setHtmlFontSize(); onMounted(() => { window.addEventListener("resize", setHtmlFontSize, false); }); onBeforeUnmount(() => { window.removeEventListener("resize", setHtmlFontSize, false); }); return { designs, referDesign, setHtmlFontSize, }; };
vue-cli3 中使用rem布局
1. 裝包postcss-px2rem及px2rem-loader
npm install postcss-px2rem px2rem-loader --save
2. 在根目錄src中新建utils目錄下新建rem.js等比適配文件,內(nèi)容如下
// rem等比適配配置文件 // 基準(zhǔn)大小 const baseSize = 16 // 設(shè)置 rem 函數(shù) function setRem () { // 當(dāng)前頁(yè)面寬度相對(duì)于 1920寬的縮放比例,可根據(jù)自己需要修改。 const scale = document.documentElement.clientWidth / 1920 // 設(shè)置頁(yè)面根節(jié)點(diǎn)字體大?。ā癕ath.min(scale, 2)” 指最高放大比例為2,可根據(jù)實(shí)際業(yè)務(wù)需求調(diào)整) document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px' } // 初始化 setRem() // 改變窗口大小時(shí)重新設(shè)置 rem window.onresize = function () { setRem() }
3.在main.js中引入適配文件
import './utils/rem'
4.到vue.config.js中配置插件
// 引入等比適配插件 const px2rem = require('postcss-px2rem') // 配置基本大小 const postcss = px2rem({ // 基準(zhǔn)大小 baseSize,需要和rem.js中相同 remUnit: 16 }) // 使用等比適配插件 module.exports = { lintOnSave: true, css: { loaderOptions: { postcss: { plugins: [ postcss ] } } } }
到此這篇關(guān)于Vue3基于 rem 比例縮放方案的文章就介紹到這了,更多相關(guān)Vue3比例縮放內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決echarts vue數(shù)據(jù)更新,視圖不更新問(wèn)題(echarts嵌在vue彈框中)
這篇文章主要介紹了解決echarts vue數(shù)據(jù)更新,視圖不更新問(wèn)題(echarts嵌在vue彈框中),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07Vue使用el-tree 懶加載進(jìn)行增刪改查功能的實(shí)現(xiàn)
這篇文章主要介紹了Vue使用el-tree 懶加載進(jìn)行增刪改查,以懶加載的形式展示,目錄根據(jù)需求需要有新增 編輯 刪除 操作以及操作后的刷新樹(shù)結(jié)構(gòu),具體實(shí)現(xiàn)代碼跟隨小編一起看看吧2021-08-08vue emit之Property or method “$$v“ i
這篇文章主要介紹了vue emit之Property or method “$$v“ is not defined的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06使用Vue的slot插槽分發(fā)父組件內(nèi)容實(shí)現(xiàn)高度復(fù)用、更加靈活的組件(推薦)
這篇文章主要介紹了使用Vue的slot插槽分發(fā)父組件內(nèi)容實(shí)現(xiàn)高度復(fù)用、更加靈活的組件 ,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-05-05Element-UI中關(guān)于table表格的那些騷操作(小結(jié))
這篇文章主要介紹了Element-UI中關(guān)于table表格的那些騷操作(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Vue組合式API如何正確解構(gòu)props不會(huì)丟失響應(yīng)性
響應(yīng)式?API?賦予了組合式?API?一大坨可能性的同時(shí),代碼精簡(jiǎn),雖然但是,我們應(yīng)該意識(shí)到響應(yīng)性的某些陷阱,比如丟失響應(yīng)性,在本文中,我們將學(xué)習(xí)如何正確解構(gòu)?Vue?組件的?props,使得?props?不會(huì)丟失響應(yīng)性2024-01-01手拉手教你如何處理vue項(xiàng)目中的錯(cuò)誤
在項(xiàng)目開(kāi)發(fā)中經(jīng)常遇到各種報(bào)錯(cuò),每次總是通過(guò)這樣或那樣的辦法解決掉,這篇文章主要給大家介紹了關(guān)于如何處理vue項(xiàng)目中錯(cuò)誤的相關(guān)資料,需要的朋友可以參考下2022-06-06