Vue3基于?rem?比例縮放方案示例詳解
Vue3基于 rem 比例縮放方案
本縮放方案置于hooks中即可。于App.vue中引入并調(diào)用。會在頁面DOM結(jié)構(gòu)最外層增加響應(yīng)式的font-size屬性樣式更改。

主要包含了以下內(nèi)容
1.接口和類型定義:
DesignParms:設(shè)計稿參數(shù)的接口定義,包括寬度、高度和字體大小等信息。UseRemOption:使用 rem 的配置參數(shù)的接口定義,包括延遲觸發(fā)時間。Designs:設(shè)計稿集合的類型定義,是一個由DesignParms構(gòu)成的數(shù)組。
2.默認(rèn)設(shè)計稿方案和配置參數(shù):
DEFAULT_DESIGNS:默認(rèn)的設(shè)計稿方案,包含多個不同分辨率下的設(shè)計稿信息。DEFAULT_OPTION:默認(rèn)的配置參數(shù),包括延遲觸發(fā)時間。
3.useEqualScaling 函數(shù):
- 該函數(shù)接受設(shè)計稿集合和配置參數(shù)作為參數(shù),并返回縮放信息和方法。
- 函數(shù)內(nèi)部根據(jù)窗口大小和設(shè)計稿信息計算最合適的設(shè)計稿作為參考設(shè)計稿。
- 在頁面加載和窗口大小改變時,會觸發(fā)
setHtmlFontSize方法進(jìn)行根節(jié)點字體大小的計算和設(shè)置。 - 函數(shù)返回設(shè)計稿集合、參考設(shè)計稿和設(shè)置根節(jié)點字體大小的方法
/**
* 基于rem 的比例縮放方案
* @author wangguanjie 2022.06.09
*/
import { onBeforeUnmount, onMounted, ref } from "vue";
/**
* 設(shè)計稿參數(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è)計稿方案
*/
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ā)延時,默認(rèn)2022
delay: 0,
};
/**
* 等比縮放方案
* @author wangguanjie 2022.06.09
* @description 該方案支持多設(shè)計稿
* @param designs 設(shè)計稿集合
* @param option 縮放配置參數(shù)
* @returns 縮放信息、方法
*/
export const useEqualScaling = function (
designs: Designs = DEFAULT_DESIGNS,
option: UseRemOption = DEFAULT_OPTION
) {
let timer: number | undefined;
// 確保有設(shè)計稿可參考
designs = designs.length ? designs : DEFAULT_DESIGNS;
// 將設(shè)計搞進(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è)計稿
const descendingDesigns = designs.map((d) => d).reverse();
// 瀏覽器適配所參考的設(shè)計稿
const referDesign = ref(designs[0]);
/**
* 根據(jù)多份設(shè)計搞自適應(yīng)根節(jié)點字號
*/
const setHtmlFontSize = () => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
const { clientWidth: docW, clientHeight: docH } =
document.documentElement;
// 匹配最佳設(shè)計稿
const hasNewReferDesignIndex = designs.findIndex(
(d) => d.width >= docW && d.height >= docH
);
if (hasNewReferDesignIndex !== -1) {
referDesign.value = designs[hasNewReferDesignIndex];
} else {
// 優(yōu)先篩選寬度符合的設(shè)計搞
const accordWidthDesigns = descendingDesigns.filter(
(d) => d.width <= docW
);
// 再確認(rèn)最接近設(shè)計稿高度的設(shè)計稿
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è)計稿變更根節(jié)點字號
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)前頁面寬度相對于 1920寬的縮放比例,可根據(jù)自己需要修改。
const scale = document.documentElement.clientWidth / 1920
// 設(shè)置頁面根節(jié)點字體大小(“Math.min(scale, 2)” 指最高放大比例為2,可根據(jù)實際業(yè)務(wù)需求調(diào)整)
document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px'
}
// 初始化
setRem()
// 改變窗口大小時重新設(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue+tracking.js 實現(xiàn)前端人臉檢測功能
這篇文章主要介紹了Vue+tracking.js 實現(xiàn)前端人臉檢測功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
vue 彈窗時 監(jiān)聽手機(jī)返回鍵關(guān)閉彈窗功能(頁面不跳轉(zhuǎn))
這篇文章主要介紹了vue 彈窗時 監(jiān)聽手機(jī)返回鍵關(guān)閉彈窗功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值(頁面不跳轉(zhuǎn)) ,需要的朋友可以參考下2019-05-05
Vue2?this?能夠直接獲取到?data?和?methods?的原理分析
這篇文章主要介紹了Vue2?this能夠直接獲取到data和methods的原理分析,因為methods里的方法通過bind指定了this為new?Vue的實例2022-06-06
你了解vue3.0響應(yīng)式數(shù)據(jù)怎么實現(xiàn)嗎
這篇文章主要介紹了你了解vue3.0響應(yīng)式數(shù)據(jù)怎么實現(xiàn)嗎,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-06-06
Vue2.0利用vue-resource上傳文件到七牛的實例代碼
本篇文章主要介紹了Vue2.0利用vue-resource上傳文件到七牛的實例代碼,具有一定的參考價值,有興趣的可以了解一下2017-07-07
詳解win7 cmd執(zhí)行vue不是內(nèi)部命令的解決方法
這篇文章主要介紹了詳解win7 cmd執(zhí)行vue不是內(nèi)部命令的解決方法的相關(guān)資料,這里提供了解決問題的詳細(xì)步驟,具有一定的參考價值,需要的朋友可以參考下2017-07-07

