Vue3基于?rem?比例縮放方案示例詳解
Vue3基于 rem 比例縮放方案
本縮放方案置于hooks中即可。于App.vue中引入并調(diào)用。會(huì)在頁面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ì)稿。
- 在頁面加載和窗口大小改變時(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)前頁面寬度相對(duì)于 1920寬的縮放比例,可根據(jù)自己需要修改。
const scale = document.documentElement.clientWidth / 1920
// 設(shè)置頁面根節(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)文章
Vue+tracking.js 實(shí)現(xiàn)前端人臉檢測(cè)功能
這篇文章主要介紹了Vue+tracking.js 實(shí)現(xiàn)前端人臉檢測(cè)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
vue 彈窗時(shí) 監(jiān)聽手機(jī)返回鍵關(guān)閉彈窗功能(頁面不跳轉(zhuǎn))
這篇文章主要介紹了vue 彈窗時(shí) 監(jiān)聽手機(jī)返回鍵關(guān)閉彈窗功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值(頁面不跳轉(zhuǎn)) ,需要的朋友可以參考下2019-05-05
Vue2?this?能夠直接獲取到?data?和?methods?的原理分析
這篇文章主要介紹了Vue2?this能夠直接獲取到data和methods的原理分析,因?yàn)閙ethods里的方法通過bind指定了this為new?Vue的實(shí)例2022-06-06
詳解nginx配置vue h5 history去除#號(hào)
這篇文章主要介紹了詳解nginx配置vue h5 history去除#號(hào),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
你了解vue3.0響應(yīng)式數(shù)據(jù)怎么實(shí)現(xiàn)嗎
這篇文章主要介紹了你了解vue3.0響應(yīng)式數(shù)據(jù)怎么實(shí)現(xiàn)嗎,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-06-06
Vue項(xiàng)目打包后出現(xiàn)的路徑問題以及解決方案
本文詳細(xì)探討了Vue項(xiàng)目打包后常見的路徑問題,包括靜態(tài)資源路徑錯(cuò)誤、路由路徑錯(cuò)誤、環(huán)境變量路徑錯(cuò)誤和publicPath配置錯(cuò)誤,并提供了相應(yīng)的解決方案,通過正確配置這些路徑,可以有效解決Vue項(xiàng)目在打包后的資源加載問題,確保項(xiàng)目在生產(chǎn)環(huán)境中的正常運(yùn)行2025-11-11
Vue2.0利用vue-resource上傳文件到七牛的實(shí)例代碼
本篇文章主要介紹了Vue2.0利用vue-resource上傳文件到七牛的實(shí)例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07
詳解win7 cmd執(zhí)行vue不是內(nèi)部命令的解決方法
這篇文章主要介紹了詳解win7 cmd執(zhí)行vue不是內(nèi)部命令的解決方法的相關(guān)資料,這里提供了解決問題的詳細(xì)步驟,具有一定的參考價(jià)值,需要的朋友可以參考下2017-07-07
vue與iframe之間的信息交互的實(shí)現(xiàn)
這篇文章主要介紹了vue與iframe之間的信息交互的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04

