Vue3基于rem比例H5縮放方案示例詳解
hooks:于App.vue中引入并調(diào)用
會(huì)在頁(yè)面DOM結(jié)構(gòu)最外層增加響應(yīng)式的font-size屬性樣式更改。
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, }; };
引入依賴方案
裝包postcss-px2rem及px2rem-loader
npm install postcss-px2rem px2rem-loader --save
在根目錄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() }
在main.js中引入適配文件
import './utils/rem'
到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 ] } } } }
以上就是Vue3基于rem比例H5縮放方案示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Vue3 rem比例H5縮放的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue實(shí)現(xiàn)pdf在線預(yù)覽功能的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何使用Vue實(shí)現(xiàn)pdf在線預(yù)覽功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-03-03Vue中的基礎(chǔ)過渡動(dòng)畫及實(shí)現(xiàn)原理解析
這篇文章主要介紹了Vue中的基礎(chǔ)過渡動(dòng)畫原理解析,需要的朋友可以參考下2018-12-12vue項(xiàng)目如何讓局域網(wǎng)ip訪問配置設(shè)置
這篇文章主要介紹了vue項(xiàng)目如何讓局域網(wǎng)ip訪問配置設(shè)置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2022-09-09elementUI中el-dropdown的command實(shí)現(xiàn)傳遞多個(gè)參數(shù)
這篇文章主要介紹了elementUI中el-dropdown的command實(shí)現(xiàn)傳遞多個(gè)參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08