背景
- 已有设备
- ipad :1024*768
- 安卓大屏:1920*1080
- vue版本脚手架cli2.0
- 已经开发了 ipad 版本,需要安卓大屏也兼容显示
问题
- 默认按ipad尺寸开发,固定是px写死了。
- 为了适配不同尺寸,使用了 viewport 页面压缩技术,把安卓大屏进行放大显示
- 由于放大后,会导致部分 图片,按钮出现起毛,或模糊的情况
解决方案
思路
使用rem单位技术,动态设置 font-size达到不同设备的兼容。
具体流程
- 使用postcss-pxtorem动态单位,把原有的ipad版本所有 px的单位,全都转为rem版本
- 在构建的时候根据指定的宽度参数,一生成两个不同版本的rem项目
- 通过首页的判断当前浏览器的宽度 ,动态设置html的 font-size,从而使rem动态解析对应的尺寸
缺点
- 需要部署两套环境,为什么不能只搞一套呢?
- 因为很多代码样式是直接写在了vue页面里面,不能通过不同的环境动态加载不同的css
集成rem流程
安装插件
npm i postcss-pxtorem -D
配置
- 由于集成了 postcss,只需要配置.postcssrc.js .postcssrc.js
//.postcssrc.js
//默认不设置
console.log("process.env.BUILD_DEVICE----",process.env.BUILD_DEVICE)
const deviceWidth = (process.env.BUILD_DEVICE == "bigScreen")?130:98
console.log("deviceWidth----",deviceWidth)
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {},
//注意
//安卓大屏使用的是 1092 * 1080,需要设置 130
//注意装扮灵 尺寸为 1024*768,需要设置 98
"postcss-pxtorem": {
rootValue: deviceWidth,
unitPrecision: 5,
propList: ['*'],
selectorBlackList: [],
replace: true,
mediaQuery: false,
minPixelValue: 12,
},
}
}
package.json
//package.json
//项目启动添加 BUILD_DEVICE 设备类型 有ipad和bigScreen
"build-dev": "cross-env RUN_TYPE=build BUILD_TYPE=dev BUILD_DEVICE=ipad npm run webpack-build",
"build-dev-bigScreen": "cross-env RUN_TYPE=build BUILD_TYPE=dev BUILD_DEVICE=bigScreen npm run webpack-build",
webpack.base.conf.js //添加映射的参数
plugins: [
new webpack.DefinePlugin({
'process.env.BUILD_DEVICE':JSON.stringify(process.env.BUILD_DEVICE),
}),
],
//这样才具体的业务代码 也可以正常访问 process.env.BUILD_DEVICE
使用flexible动态计算当前的rem对应的 font-size值
//rem.js
//每次页面放大缩小,加载都会重新计算对应的font-size,来影响对应rem值大小
(function flexible (window, document) {
var docEl = document.documentElement
var dpr = window.devicePixelRatio || 1
// adjust body font size
function setBodyFontSize () {
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
}
else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
index.html 引入 rem.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta http-equiv="pragram" content="no-cache">
<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Expires" content="0">
<title>XXXX</title>
</head>
<body>
<div id="app"></div>
<script src="http://xxxxxxx:17280/commonJS/rem.js"></script>
</body>
</html>