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-03
Vue中的基礎(chǔ)過(guò)渡動(dòng)畫(huà)及實(shí)現(xiàn)原理解析
這篇文章主要介紹了Vue中的基礎(chǔ)過(guò)渡動(dòng)畫(huà)原理解析,需要的朋友可以參考下2018-12-12
vue項(xiàng)目如何讓局域網(wǎng)ip訪問(wèn)配置設(shè)置
這篇文章主要介紹了vue項(xiàng)目如何讓局域網(wǎng)ip訪問(wèn)配置設(shè)置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2022-09-09
elementUI中el-dropdown的command實(shí)現(xiàn)傳遞多個(gè)參數(shù)
這篇文章主要介紹了elementUI中el-dropdown的command實(shí)現(xiàn)傳遞多個(gè)參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08

