一、背景
- 最近一直有用户反馈页面的在 iPad 上显示的内容非常小,页面上的文字看不清楚
- 大的屏幕 理应看到更大的图标和文字,结果却没有达到预期
二、问题
- 页面大小没有根据 移动设备的视口宽度 进行自适应
- 由于项目成立的时间比较长,工程中 css 的 单位不统一,例如:px / em / rem 等
三、对问题的思考
- 如何 实现 页面 根据 视口的宽度进行自适应?
- 如何对这么多的 px 单位进行转换?
四、复习 em / rem
-
em
-
rem 英文的完整翻译是:Root Element
截图来自: MDN
链接:https://developer.mozilla.org/zh-CN/docs/Web/CSS/length
五、解决问题的思考
1. 在网上查找了大量的资料,业界的主要解决方案是 rem,因此楼主也采用了 rem 的方式。
采用 rem 的方式,那自然是引入了 amfe-flexible 库进行实现。问题1迎刃而解
2. 如何实现工程中的 px 转 rem,这是一个头疼的问题。
2.1 直接手动把工程中的所有 px 换算为 rem ? 这不现实,成本太高
2.2 写一个工具先把 工程中的所有 px 换算为 rem ? 这可行,但是还是不够自动化,后期维护恶心
2.3 webpack 打包的时候,把 px 转 rem ? 这可行,实现之后,后期无需维护,只要随着工程构建,就可以实现转换
六、代码的实现
解决问题 1
- 引入 amfe-flexible 实现根节点 rem 配置
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<!--这里的文件可以根据自己的实际情况,将源码copy一份进行修改-->
<script src="./node_modules/amfe-flexible/index.js"></script>
</head>
解决问题 2
- 首先我们知道,loaders 装载器的运行顺序是 从后往前;pulgins 外挂的 执行顺序是 从前往后。
- 那么即使我们在工程中使用 less / sass 写样式,最后还是要经过 css-loader 进行处理,那么我们 对 px 转 rem 的操作,只需要在 less-loader/sass-loader 和 css-loader 之间进行即可
- 楼主采用的 px2rem-loader
- 由于项目工程 是 vue-cli2 搭起来的,因此我们找到 util.js
1. 安装
yarn add px2rem-loader -D
2. util.js 配置
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: options.sourceMap,
importLoaders: 1
}
}
// 关键点 !!
const px2remLoader = {
loader: 'px2rem-loader',
options: {
remUnit: 50, // 项目规范以50px为基准数,可根据自己额实际情况而定
exclude: /(node_module)/
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
let loaders = [cssLoader, px2remLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
若有些特定的情形不需要转换 px,那可进行如下配置
.selector {
width: 150px;
height: 64px; /*px*/
font-size: 28px; /*px*/
border: 1px solid #ddd; /*no*/
}
px2rem-loader 基于 px2rem 实现,很多用法和 px2rem 类似
https://github.com/Jinjiang/px2rem-loader
配置完成,本地运行,看到如下效果,我们就完成了一大步
七、遇到的问题
-
打包构建时出现以下的错误
-
解决方案: 升级 happypack,问题解决
// package.json
"devDependencies": {
"happypack": "5.0.1",
"px2rem-loader": "^0.1.9"
}