大屏自适应的核心目标有:
- 字体大小随屏幕尺寸自适应变化
- 自动撑满全屏
- 弹性布局(使用 css 的布局)
不会留白,但是部分分辨率下部分屏幕会有拉伸的情况
var _el = this.$refs.appContain
var hScale = window.innerHeight / 1080
var wScale = window.innerWidth / 1920
_el.style.transform = 'scale(' + wScale + ',' + hScale + ') translateX(-50%)'
设置系统缩放比,适配各分辨率,这种方式会导致在不同分辨率下会有留白的情况
export function refreshScale(){
let baseWidth = document.documentElement.clientWidth;
let baseHeight = document.documentElement.clientHeight;
let appStyle = document.getElementById('app').style;
let realRatio = baseWidth/baseHeight
let designRatio = 16/9
let scaleRate = baseWidth/1920
if(realRatio>designRatio){
scaleRate = baseHeight/1080
}
appStyle.transformOrigin = 'left top';
appStyle.transform=`scale(${scaleRate}) translateX(-50%)`;
appStyle.width = `${baseWidth/scaleRate}px`
}
- 可不使用
export const echartsSize = function (size,defalteWidth = 1920) {
let docEl = document.documentElement,
clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
if (!clientWidth) return;
let fontSize = (clientWidth / defalteWidth);
return Number((size*fontSize).toFixed(3));
}
完整代码
- 新建mix.js文件,复制进去后,直接包裹外层容器,需注意:app样式直接设置成100vw,100vh
- 包裹所有内容的容器需要设置为以下样式
.scale-container {
/*父级宽100vw,高100vh。子盒子宽高1920*1080可以做大屏显示居中缩放 */
width: 1920px;
height: 1080px;
/* 根据父级定位,配合transform用来居中 */
position: absolute;
left: 50%;
/* 更改转换元素的位置 */
transform-origin: left top;
/* 超出隐藏 */
overflow: hidden;
}
完整代码
// 屏幕适配 mixin 函数
// * 默认缩放值
const scale = {
width: '1',
height: '1',
}
// * 设计稿尺寸(px)
var baseWidth = 1920
var baseHeight = 1080
// * 需保持的比例(默认1.77778)
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
export default {
data() {
return {
// * 定时函数
drawTiming: null,
}
},
mounted() {
//加载后先计算一遍缩放比例
this.calcRate()
//生成一个监听器:窗口发生变化从新计算计算一遍缩放比例
window.addEventListener('resize', this.resize)
},
beforeDestroy() {
window.removeEventListener('resize', this.resize)
},
methods: {
calcRate() {
// 直接暴力铺满,一劳永逸
var _el = this.$refs.appContain
var hScale = window.innerHeight / 1080
var wScale = window.innerWidth / 1920
_el.style.transform = 'scale(' + wScale + ',' + hScale + ') translateX(-50%)'
return
// 设置系统缩放比,适配各分辨率,但是会留白
const baseWidth = document.documentElement.clientWidth
const baseHeight = document.documentElement.clientHeight
const appStyle = this.$refs.appContain.style
const realRatio = baseWidth / baseHeight
const designRatio = 16 / 9
let scaleRate = baseWidth / 1920
if (realRatio > designRatio) {
scaleRate = baseHeight / 1080
}
appStyle.transformOrigin = 'left top'
appStyle.transform = `scale(${scaleRate}) translateX(-50%)`
appStyle.width = `${baseWidth / scaleRate}px`
},
resize() {
//先清除计时器
clearTimeout(this.drawTiming)
//开启计时器
this.drawTiming = setTimeout(() => {
this.calcRate()
}, 200)
},
},
}
使用rem进行自适应,自动铺满全屏,部分分辨率会出现布局混乱
- 在入口如添加修改字体大小的代码
cnpm i postcss-plugin-px2rem
;(function (designWidth, minWidth) {
const docEle = document.documentElement
const screenRatioByDesign = 16 / 9
function setHtmlFontSize() {
var screenRatio = docEle.clientWidth / docEle.clientHeight
var fontSize =
((screenRatio > screenRatioByDesign ? screenRatioByDesign / screenRatio : 1) * docEle.clientWidth) / 10
docEle.style.fontSize = fontSize.toFixed(3) + 'px'
}
setHtmlFontSize()
window.addEventListener('resize', setHtmlFontSize)
})(1920, 1024)
接着在vue.config.js中配置
css: {
extract: false,
sourceMap: false,
// css预设器配置项
loaderOptions: {
postcss: {
plugins: [
require('postcss-plugin-px2rem')({
// 换算基数, 默认100 ,这样的话把根标签的字体规定为1rem为50px,这样就从设计稿上量出多少个px直接在代码中写多上px了。
rootValue: 192,
//允许REM单位增长到的十进制数字。
unitPrecision: 5,
//默认值是一个空数组,这意味着禁用白名单并启用所有属性。
//propWhiteList: [],
// propBlackList: [], //黑名单
//默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
exclude: /(node_module)/,
// selectorBlackList: [], //要忽略并保留为px的选择器
//(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
// ignoreIdentifier: false,
replace: false, // (布尔值)替换包含REM的规则,而不是添加回退。
mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
minPixelValue: 3, //设置要替换的最小像素值(3px会被转rem)。 默认 0
}),
],
},
less: {
lessOptions: {
javascriptEnabled: true,
},
},
},
},