1.分类
第一种是纯使用px单位,没有做适配的项目
如果你是这个类型,那么这篇文章看对了,待会我会说以下这种类型的项目做适配的额完美方法。
第二种是做大屏适配的,即无滚动条但要跟随屏幕大小自适应的
这种类型的项目在这篇文章种也可获得较为完美的解决方式
第三种是使用rem适配的,但是项目有问题的
使用此方法带来的问题是,当在低分辨率的情况下,字体会变大一些,或者项目整体看起来好像有些微变化,反正看着和设计图不太像。
2.对于使用px单位未做适配的项目改造方案
核心是根据页面的宽度除以1920,然后设置body的zoom属性
mounted () { this.bodyScale() }, //method中 bodyScale () { //获取当前分辨率下的可是区域宽度 var devicewidth = document.documentElement.clientWidth var scale = devicewidth / 1920 // 分母——设计稿的尺寸 document.body.style.zoom = scale//放大缩小相应倍数 alert(scale) }
3.对于大屏可视化适配方案
主要是横向和纵向不要有滚动条,使用的技术主要是scale缩放技术,其次是rem,这里以主流的scale方案
第一步, src目录下utils文件下新建drawMixin.js文件,将以下代码粘贴进去
// 屏幕适配 mixin 函数 // * 默认缩放值 const scale = { width: '1', height: '1', } // * 设计稿尺寸(px) const baseWidth = 1920 const 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 () { const appRef = this.$refs["appRef"] if (!appRef) return // 当前宽高比 const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5)) if (appRef) { if (currentRate > baseProportion) { // 表示更宽 scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5) scale.height = (window.innerHeight / baseHeight).toFixed(5) appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)` } else { // 表示更高 scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5) scale.width = (window.innerWidth / baseWidth).toFixed(5) appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)` } } }, resize () { clearTimeout(this.drawTiming) this.drawTiming = setTimeout(() => { this.calcRate() }, 200) } }, }
第二步,在根组件如app.vue或index.vue文件(页面最外层的标签)写入以下代码
我用的是mixin混入,如果不想这么搞,可以按部就班的把drawMixin.js里面的数据放在该放的位置上即可
<div id="index" ref="appRef"> //加一个ref
import drawMixin from "../utils/drawMixin"
export default { mixins: [drawMixin], data () { return { } }}
第三步,设置根标签的样式
这一步很重要,具体标签名根据自己项目来,就是页面居中,脱离文档流,加一个溢出隐藏,就不会出现滚动条了。
#app { width: 1920px; height: 1080px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); transform-origin: left top; overflow: hidden; }
小结:
这个方案非常适合大屏项目,我在想能不能用于其他类型的项目呢,尝试了一番后发现都不太理想,主要问题在于滚动条的处理上,如果你有好的方法,不妨评论区交流一番。
4.使用rem的
第一个问题是在低分辨率下字体有些大的问题
是因为浏览器最小字体大小是12px,可以使用缩放transform:scale()。如:-webkit-transform: scale(0.5)
还有一个问题,就是使用rem设置如elementUI这种第三方Ui框架,这种底层样式都是用px单位写的,所以我们需要将px转化为rem单位
转换的方法如下有两个:
先说最简便的,如果你使用vscode且安装了pxtorem插件,只需要全局搜索px,然后ALT+Z全局替换并转换rem单位即可。
其次可以封装一个方法用于转换:
在vue项目的/node_modules/element-ui/lib/theme-chalk/index.css 路径下找到index.css文件,它就是elementUl的css样式文件,它里面都是用px做单位的,然后使用下面的函数将其转化
px和rem单位互转,参数介绍:
content: 样式表的内容 (style里到css内容),
unit: 需要替换的单位名称 (例 px),
updateUnit: 替换后的单位名称 (例 rem),
rule: 单位换算规则,多少rem = px || px = rem ,
例如:当rule为100时即表示 1rem = 100px
function pxAndRemInterturn({content,unit,rule,updateUnit}){ rule = rule || 100 if(!rule)return content; const reg = { px : /[\:]*[\s]*[-]*[\s]*[0-9]*[\.]*[0-9]*\p\x/g, rem: /[\:]*[\s]*[-]*[\s]*[0-9]*[\.]*[0-9]*rem/g, number: /[0-9]*[\.]*[0-9]*/g } // 获取到所有匹配的内容 const res = content.match(reg[unit]) // 传进来的是正则匹配的结构内容 function getRightData(arr){ const result = [] for(let i = 0; i <arr.length;i++){ result.push(Number(arr[i].replace(new RegExp(' ', "gm"), '').replace(':','').replace(unit,''))) } return result } const rightData = getRightData(res) // 单位换算 function unitConversion({num,unit,updateUnit,rule}){ let res = '' if(unit === 'px' && updateUnit === 'rem'){ res = num / rule }else if(unit === 'rem' && updateUnit === 'px'){ res = num * rule } return ' ' + res + updateUnit } for(let i=0;i < rightData.length;i++){ let txt = unitConversion({ num:rightData[i], unit, updateUnit, rule }) if(res[i].indexOf(':') >= 0){ txt = ': '+ txt } content = content.replace(res[i],txt) } return content }