全屏页面适配
如需安装所有解决方案,请参考全量解决方案安装
适用场景
页面大小为屏幕可视区域大小,项目页面需要完整的显示在屏幕中,且保持UI设计的尺寸比例。
方案
使用postcss-pxtorem, 将页面单位转换为rem,即与页面根元素字体大小相关,再根据UI设计尺寸和页面的尺寸,计算合适的一个比例,使得页面能够完整的显示在页面中,且保持页面的设计比例
TIP
注意:页面部分区域需要自适应剩余区域的,需要自行调整样式。
单独安装此hook
shell
npm install @havue/use-full-screen-adapt --save
shell
yarn add @havue/use-full-screen-adapt
shell
pnpm install @havue/use-full-screen-adapt
步骤
安装postcss-pxtorem
bash
npm install -D postcss-pxtorem
配置环境变量
编辑 .env
文件
env
# ui 设计宽度
VITE_UI_DESIGN_WIDTH = 1280
# UI 设计高度
VITE_UI_DESIGN_HEIGHT = 740
# postcss-px-torem rootValue 值
VITE_PXTOREM_ROOTVALUE = 100
配置postcss-pxtorem
编辑 .postcssrc.cjs
js
// postcss 插件
const autoPrefixer = require('autoprefixer')
const pxtorem = require('postcss-pxtorem')
const vite = require('vite')
module.exports = ({ env }) => {
const envObj = vite.loadEnv(env, './')
return {
plugins: [
autoPrefixer(),
pxtorem({
rootValue: Number(envObj.VITE_PXTOREM_ROOTVALUE) || 16, // 根元素字体大小
unitPrecision: 5,
propList: ['*'],
replace: true,
mediaQuery: true,
minPixelValue: 1
})
]
}
}
编写动态更新根元素字体大小的代码
ts
import { useFullScreenAdapt } from 'havue'
// or
import { useFullScreenAdapt } from '@havue/hooks'
// or
import { useFullScreenAdapt } from '@havue/use-full-screen-adapt'
ts
/**
* 根据UI设计尺寸,以及当前屏幕尺寸,计算合适的根元素字体大小
* @param uiWidth UI设计宽度
* @param uiHeight UI设计高度
* @param pxtoremRootValue postcss-pxtorem的rootValue值
* @param stopOnInput 在input聚焦时,停止计算根元素字体大小,固定页面尺寸
*/
export function useFullScreenAdapt(
uiWidth: number,
uiHeight: number,
pxtoremRootValue: number = 16,
stopOnInput: boolean = false
) {
const docEl = document.documentElement
let isStopAdapt: boolean = false
const stop = () => (isStopAdapt = true)
const resume = () => (isStopAdapt = false)
function setBodyFontSize() {
if (document.body) {
setRemUnit()
if (stopOnInput) {
stopAdaptOnInputFocused(stop, resume)
}
} else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize()
/** 更改根元素字体大小 */
function setRemUnit() {
if (isStopAdapt) {
return
}
/** UI 设计比例 */
const uiRatio = uiWidth / uiHeight
const { clientWidth, clientHeight } = docEl
/** 屏幕宽高比例 */
const screenRatio = clientWidth / clientHeight
let targetWidth = clientWidth
if (uiRatio > screenRatio) {
const targetHeight = clientWidth / uiRatio
targetWidth = targetHeight * uiRatio
} else {
targetWidth = uiRatio * clientHeight
}
const rem = (targetWidth * pxtoremRootValue) / uiWidth
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
return {
stop,
resume
}
}
/**
* 输入时,暂停根元素字体自适应计算
* @param onFocus
* @param onBlur
*/
export function stopAdaptOnInputFocused(onFocus: (e?: FocusEvent) => void, onBlur: (e?: FocusEvent) => void) {
const docEl = document.documentElement
let oldBodyWidth: string
let oldBodyHeight: string
docEl.addEventListener(
'focus',
function (e) {
const target = e.target as HTMLElement
if (target.tagName === 'INPUT') {
onFocus()
const { clientWidth, clientHeight } = docEl
oldBodyWidth = docEl.style.width
oldBodyHeight = docEl.style.height
docEl.style.width = `${clientWidth}px`
docEl.style.height = `${clientHeight}px`
}
},
{ capture: true }
)
docEl.addEventListener(
'blur',
function (e) {
const target = e.target as HTMLElement
if (target.tagName === 'INPUT') {
onBlur()
docEl.style.width = oldBodyWidth
docEl.style.height = oldBodyHeight
}
},
{ capture: true }
)
}
如果已安装,则可直接引入使用
在项目入口 main.ts 中使用
ts
useFullScreenAdapt(Number(import.meta.env.VITE_UI_DESIGN_WIDTH), Number(import.meta.env.VITE_UI_DESIGN_HEIGHT), Number(import.meta.env.VITE_PXTOREM_ROOTVALUE) || 16)