VUE移动端和PC端适配方案总结

移动端和PC端适配采用的方案,之前做大屏的时候设计稿是以1920*1080的尺寸设计的,考虑到市面上的显示其尺寸包括宽为1360、1440、1600、1660这几个尺寸,我在做适配的时候基本都是使用百分比和calc的方式做自适应,在PC端基本没有问题,实际的大屏分辨率也都是1920*1080的,所以一直都没有问题,这次大屏客户的屏幕是3840*2160的分辨率,是之前的2倍,显示效果可想而知,与设计相差太多,所以从新考虑了适配方案,采用postcss-px2rem的方案

前提:项目是使用官网的方式创建的vue2.0版本的项目

项目目录

大屏页面

这个方案主要分两步:这两步是完全独立的过程但又互相影响
1、根据分辨率动态设置html的字体大小;
2、引入postcss-px2rem将css中的px转成rem;

html设置字体大小

有两种方式为根节点html动态设置字体大小,

第一种:使用lib-flexible.js设置

这个插件是淘宝团队开发的,主要应用于移动端,代码中有一段限制了字体动态设置的屏幕大小是540px,也就是说大于540px之后html的字体大小就不变了。

function refreshRem()
    var width = docEl.getBoundingClientRect().width;
    if (width / dpr > 540) {
        width = 540 * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}

所以在移动端可以直接引用这个文件
下载方式:执行yarn add lib-flexible
引入方式:在main.js中通过import 'lib-flexible'引入
计算规则:他会给html设置字体大小为当前屏幕宽度除以10的大小,比如iphone手机的屏幕物理像素是375*667,那html的字体大小就是37.5px

第二种:模仿lib-flexible自己写一个

lib-flexible只适用于移动端,所以PC端需要模仿flexible自己按需求写一个,网上有很多这种代码,思路都是根据浏览器可视区的大小动态设置根节点html的字体大小,我暂且把文件命名为rem.js

// 基础字体大小
const baseValue = 75
// 可视区的大小,移动端是屏幕的宽度,PC端是浏览器可视区的宽度
let clientWidth = 0
// 设计稿的宽度
const designWidth = 1920
// 设置 rem 函数
function setRem () {
    // 当前页面宽度相对于 1920宽的缩放比例,可根据自己需要修改。
    clientWidth = document.documentElement.clientWidth
    const scale = clientWidth / designWidth
    // 设置页面根节点字体大小(“Math.min(scale, 2)” 指最高放大比例为2,可根据实际业务需求调整)
    document.documentElement.style.fontSize = baseValue * scale + 'px'
}
// 初始化
setRem()
// 改变窗口大小时重新设置 rem
window.onresize = function () {
    setRem()
}

这种方式更适用于PC端,baseValue可以随意调整,但要跟postcss插件配合使用

配置postcss-px2rem

把px转换成rem的工具有两个,一个是post-css2rem另一个是postcss-pxtorem,两个用哪个都行,但是我看postcss-px2rem五年没有跟新了,本着有新的不用旧的原则,我把px2rem换成了pxtorem,具体有啥区别我也不知道,反正效果就是把px转成rem,结果都一样
先说postcss-px2rem
下载方式: yarn add postcss-px2rem
配置方式:在跟目录下新建vue.config.js文件,复制下面代码上去

// 引入等比适配插件
const px2rem = require('postcss-px2rem')

// 配置基本大小
const postcss = px2rem({
    // 基准大小 baseSize,需要和rem.js中相同
    remUnit: 75
})

module.exports = {
    lintOnSave:true,
    css:{
        loaderOptions:{
            postcss:{
                plugins:[postcss]
            }
        }
    }
}

再说说postcss-pxtorem
下载方式: yarn add postcss-pxtorem@5.1.1,我的项目执行yarn add postcss-pxtorem默认下载的是6.0版本结果运行不起来,所以我降低了版本
配置方式:在跟目录下新建postcss.config.js文件,复制下面代码上去,或者在vue.config.js中像px2rem那么配置也是可以的

//在postcss.config.js中配置
module.exports = {
    "plugins": {
        "postcss-pxtorem": {
            //换算基数,默认100,把根标签的font-size规定为1rem为50px,在设计稿上量出多少px直接在代码中写多少px
            rootValue: 75,
            //保留rem小数点多少位
            unitPrecision: 5,
            //存储将被转换的属性列表,'!font-size' 即不对字体进行rem转换
            propList: ['*', '!border', '!font-size'],
            //要忽略并保留为px的选择器,例如fs-xl类名,里面有关px的样式将不被转换,支持正则写法。
            selectorBlackList: ['.radius'],
            replace: true,
            //(布尔值)媒体查询( @media screen 之类的)中不生效
            mediaQuery: false,
            //设置要替换的最小像素值,px小于12的不会被转换
            minPixelValue: 12,
            //默认值是一个空数组,这意味着禁用白名单并启用所有属性
            //propWhiteList: [],
            //黑名单
            propBlackList: ['font-size'],
        }
    }
}

或者

//在vue.config.js中配置
// 引入等比适配插件
const pxtorem = require('postcss-pxtorem')

// 配置基本大小
const postcss = pxtorem({
    //换算基数,默认100,把根标签的font-size规定为1rem为50px,在设计稿上量出多少px直接在代码中写多少px
    rootValue: 75,
    //保留rem小数点多少位
    unitPrecision: 5,
    //存储将被转换的属性列表,'!font-size' 即不对字体进行rem转换
    propList: ['*', '!border', '!font-size'],
    //要忽略并保留为px的选择器,例如fs-xl类名,里面有关px的样式将不被转换,支持正则写法。
    // selectorBlackList: ['.radius'],
    // 是否删除px的原有样式
    replace: true,
    //(布尔值)媒体查询( @media screen 之类的)中不生效
    mediaQuery: false,
    //设置要替换的最小像素值,px小于12的不会被转换
    minPixelValue: 12,
    //默认值是一个空数组,这意味着禁用白名单并启用所有属性
    // propWhiteList: [],
    //黑名单
    // propBlackList: ['font-size'],
})

// 使用等比适配插件
module.exports = {
    lintOnSave: true,
    css: {
        loaderOptions: {
            postcss: {
                plugins: [
                    postcss
                ]
            }
        }
    }
}

这两个post插件的计算规则都是一样的,remUnit和rootValue的性质相同,转换规则就是将你页面的样式除以这个值,比如你页面的某个元素设置成宽度750px,那么除以这个值就会转换成10rem,这个值是不变的,不随浏览器可视区的宽度变化而变化,在1920的显示器上转成10rem,在1360的显示器上也转成10rem

lib-flexible与postcss如何配合使用

所以postcss需要跟flexible配合使用,我们先定义几个变量,然后缕清这几个变量之间的关系

clientWidth      //屏幕的宽度
designWidth      //设计稿的宽度
rootValue        //postcss中配置的数值
baseValue        //在自己编写的rem.js文件中的基础数值

以1920*1080尺寸的设计稿为例:假如页面有一个填满屏幕宽度的元素,元素的宽度就是designWidth
该元素通过postcss转化后的rem大小designWidth/rootvalue无论屏幕如何缩放,该值是固定的
既然该值是固定的,那么实现适配就是通过动态改变html的字体大小实现的
首先计算缩放比,因为基础是1920的尺寸,在其他尺寸的屏幕就需要等比放大或缩小
缩放比:scale = clientWidth / designWidth缩放比就是实际的屏幕宽度除以设计稿的宽度,如果实际宽度就是1920,那么scale就是1,即不缩放;如果实际屏幕是3840,那么scale就是2,即放大一倍
字体大小设置:baseValue * scale 也就是clientWidth / designWidth * baseValue
字体大小与post转化后的rem相乘就应该等于clientWidth,所以
(clientWidth / designWidth * baseValue)*(designWidth/rootvalue) = clientWidth
最后你会发现baseValue/rootvalue = 1,也就是相等,所以在实际设置中,使用上述rem.js的计算方式,只要保证baseValue和rootvalue相等就可以了
如果上面的方法很难理解的话,有一种实践出真知的方式
就是放到浏览器中测试一下,比如我的设计稿是1920*1080的,那么我就把浏览器调到1920宽,然后看html的字体大小是多少,这个字体大小就是postcss中的rootValue的值,我现在rem.js中代码执行完html设置的大小是75px,那么我postcss中的rootValue大小就应该是75

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容