Vue3基于 rem 比例缩放方案示例详解
作者:懮 俍
这篇文章主要介绍了Vue3基于rem比例缩放方案,本缩放方案置于hooks中即可,文中通过示例代码介绍了vue-cli3 中使用rem布局的方法,需要的朋友可以参考下
Vue3基于 rem 比例缩放方案
本缩放方案置于hooks中即可。于App.vue中引入并调用。会在页面DOM结构最外层增加响应式的font-size属性样式更改。
主要包含了以下内容
1.接口和类型定义:
DesignParms
:设计稿参数的接口定义,包括宽度、高度和字体大小等信息。UseRemOption
:使用 rem 的配置参数的接口定义,包括延迟触发时间。Designs
:设计稿集合的类型定义,是一个由DesignParms
构成的数组。
2.默认设计稿方案和配置参数:
DEFAULT_DESIGNS
:默认的设计稿方案,包含多个不同分辨率下的设计稿信息。DEFAULT_OPTION
:默认的配置参数,包括延迟触发时间。
3.useEqualScaling
函数:
- 该函数接受设计稿集合和配置参数作为参数,并返回缩放信息和方法。
- 函数内部根据窗口大小和设计稿信息计算最合适的设计稿作为参考设计稿。
- 在页面加载和窗口大小改变时,会触发
setHtmlFontSize
方法进行根节点字体大小的计算和设置。 - 函数返回设计稿集合、参考设计稿和设置根节点字体大小的方法
/** * 基于rem 的比例缩放方案 * @author wangguanjie 2022.06.09 */ import { onBeforeUnmount, onMounted, ref } from "vue"; /** * 设计稿参数 * @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[]; /** * 默认设计稿方案 */ 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 ]; /** * 默认配置参数 */ const DEFAULT_OPTION: Required<UseRemOption> = { // 触发延时,默认2022 delay: 0, }; /** * 等比缩放方案 * @author wangguanjie 2022.06.09 * @description 该方案支持多设计稿 * @param designs 设计稿集合 * @param option 缩放配置参数 * @returns 缩放信息、方法 */ export const useEqualScaling = function ( designs: Designs = DEFAULT_DESIGNS, option: UseRemOption = DEFAULT_OPTION ) { let timer: number | undefined; // 确保有设计稿可参考 designs = designs.length ? designs : DEFAULT_DESIGNS; // 将设计搞进行升序排序,供后续快速排查 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; }); // 降序排序的设计稿 const descendingDesigns = designs.map((d) => d).reverse(); // 浏览器适配所参考的设计稿 const referDesign = ref(designs[0]); /** * 根据多份设计搞自适应根节点字号 */ const setHtmlFontSize = () => { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { const { clientWidth: docW, clientHeight: docH } = document.documentElement; // 匹配最佳设计稿 const hasNewReferDesignIndex = designs.findIndex( (d) => d.width >= docW && d.height >= docH ); if (hasNewReferDesignIndex !== -1) { referDesign.value = designs[hasNewReferDesignIndex]; } else { // 优先筛选宽度符合的设计搞 const accordWidthDesigns = descendingDesigns.filter( (d) => d.width <= docW ); // 再确认最接近设计稿高度的设计稿 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]; } // 依据所参考的设计稿变更根节点字号 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等比适配文件,内容如下
// rem等比适配配置文件 // 基准大小 const baseSize = 16 // 设置 rem 函数 function setRem () { // 当前页面宽度相对于 1920宽的缩放比例,可根据自己需要修改。 const scale = document.documentElement.clientWidth / 1920 // 设置页面根节点字体大小(“Math.min(scale, 2)” 指最高放大比例为2,可根据实际业务需求调整) document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px' } // 初始化 setRem() // 改变窗口大小时重新设置 rem window.onresize = function () { setRem() }
3.在main.js中引入适配文件
import './utils/rem'
4.到vue.config.js中配置插件
// 引入等比适配插件 const px2rem = require('postcss-px2rem') // 配置基本大小 const postcss = px2rem({ // 基准大小 baseSize,需要和rem.js中相同 remUnit: 16 }) // 使用等比适配插件 module.exports = { lintOnSave: true, css: { loaderOptions: { postcss: { plugins: [ postcss ] } } } }
到此这篇关于Vue3基于 rem 比例缩放方案的文章就介绍到这了,更多相关Vue3比例缩放内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!