思路分析
- 使用 postcss-pxtorem 自动将 px 转为 rem;
- 结合当前浏览器窗口宽高及 orientation 来判断当前设备横竖屏状态;
- 根据当前横竖屏状态采用不同处理逻辑;
创建项目
vue init webpack vue-horizontal-demo
具体步骤
- 安装命令
npm i postcss-pxtorem --save-dev
- 打开 build/vue-loader.conf.js 加入 px2rem 配置
"use strict";
const utils = require("./utils");
const config = require("../config");
const px2rem = require("postcss-pxtorem");
const isProduction = process.env.NODE_ENV === "production";
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap;
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ["src", "poster"],
source: "src",
img: "src",
image: "xlink:href"
},
postcss: function() {
return [
px2rem({
rootValue: 75,
propList: ["*", "!border"],
minPixelValue: 1
})
];
}
};
- 在 index.html 中加入计算 font-size 代码
<script>
window.calcFontSize = () => {
document.documentElement.style.fontSize =
Math.min(
document.documentElement.clientWidth,
document.documentElement.clientHeight
) /
10 +
"px";
};
window.calcFontSize();
</script>
- 增加 horizontal-screen 全局指令
Vue.directive("horizontal-screen", {
bind(el, binding, vnode) {
let self = vnode.context;
let getDocumentSize = () => [
document.documentElement.clientWidth,
document.documentElement.clientHeight
];
// 设备开启竖屏锁定,强制横屏模式
let vertical = () => {
let [width, height] = getDocumentSize();
el.style.transform = `rotate(90deg)`;
el.style.transformOrigin = width / 2 + 'px center';
el.style.width = height + 'px';
el.style.height = width + 'px';
};
// 设备关闭竖屏锁定,横屏时,还原成正常模式
let reset = () => {
let [width, height] = getDocumentSize();
el.style.transform = `rotate(0deg)`;
el.style.width = `${width}px`;
el.style.height = `${height}px`;
};
el.resize = function() {
if (document.activeElement.nodeName === "INPUT") return; // 兼容安卓
window.calcFontSize();
if ([null, 180, 0].includes(window.orientation)) {
vertical();
} else if ([90, -90].includes(window.orientation)) {
reset();
}
};
el.resize();
el.click = e => {
if (e.target.nodeName === "INPUT") {
reset();
} else if (![90, -90].includes(window.orientation)) {
vertical();
}
};
window.addEventListener("click", el.click, false);
window.addEventListener("resize", el.resize, false); // 兼容安卓
window.addEventListener("orientationchange", el.resize, false);
},
unbind(el, binding, vnode) {
window.removeEventListener("click", el.click, false);
window.removeEventListener("resize", el.resize, false);
window.removeEventListener("orientationchange", el.resize, false);
}
});
- 在页面最外层的容器加上 'v-horizontal-screen' 即可