详解Vue-cli3.X使用px2rem遇到的问题


Posted in Javascript onAugust 09, 2019

把项目脚手架升级为cli3.X了以后,模板简洁了很多,运行起来也更加快速。但是也随之而来是某些兼容问题。比如我们要在项目钟使用px2rem来计算设计稿的时候,我们不能像以前老的脚手架那样操作了。那我们应该来如何设置呢?

首先,我们应该用NPM来安装postcss-px2rem

npm i postcss-plugin-px2rem --save -dev

然后我们需要在vue.config.js中创建一个配置。由于在vue-cli3.X中。去掉了build和config文件夹。所有的配置都放到了vue.config.js,然而这个文件脚手架并没有生成,所以需要手动在项目的根目录创建一个文件

在vue.config.js里配置

module.exports = {
  lintOnSave: true,
  css: {
    loaderOptions: {
      postcss: {
        plugins: [
          require('postcss-plugin-px2rem')({
            rootValue:75,      // 新版本的是这个值
            mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
            minPixelValue: 3 //设置要替换的最小像素值(3px会被转rem)。 默认 0
          }),
        ]
      }
    }
  },
}

这里需要说明一点。网上搜的一堆教程都强调应该增加remUnit来设置rem的计算标准。但是其实在新版后,这个值换成了rootValue这个。例如你设计稿为750的宽度标准,那么这里的值设置为75则可。

接下来还有一个工作。由于rem是根据根字体的大小来作为基准值的,然而我们的移动设备屏幕大小以及有些屏幕为视网膜屏的,会是普通屏幕的2倍,所以这个基准值我们需要根据不同设备来进行计算。这里我们在src/plugins下新建一个rem.js文件(代码如下)。

(function (win, lib) {
  var doc = win.document;
  var docEl = doc.documentElement;
  var metaEl = doc.querySelector('meta[name="viewport"]');
  var flexibleEl = doc.querySelector('meta[name="flexible"]');
  var dpr = 0;
  var scale = 0;
  var tid;
  var flexible = lib.flexible || (lib.flexible = {});

  if (metaEl) {
    //console.warn('将根据已有的meta标签来设置缩放比例');
    var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
    if (match) {
      scale = parseFloat(match[1]);
      dpr = parseInt(1 / scale);
    }
  } else if (flexibleEl) {
    var content = flexibleEl.getAttribute('content');
    if (content) {
      var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
      var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
      if (initialDpr) {
        dpr = parseFloat(initialDpr[1]);
        scale = parseFloat((1 / dpr).toFixed(2));
      }
      if (maximumDpr) {
        dpr = parseFloat(maximumDpr[1]);
        scale = parseFloat((1 / dpr).toFixed(2));
      }
    }
  }

  if (!dpr && !scale) {
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
      // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
      if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
        dpr = 3;
      } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
        dpr = 2;
      } else {
        dpr = 1;
      }
    } else {
      // 其他设备下,仍旧使用1倍的方案
      dpr = 1;
    }
    scale = 1 / dpr;
  }

  docEl.setAttribute('data-dpr', dpr);
  if (!metaEl) {
    metaEl = doc.createElement('meta');
    metaEl.setAttribute('name', 'viewport');
    metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
    if (docEl.firstElementChild) {
      docEl.firstElementChild.appendChild(metaEl);
    } else {
      var wrap = doc.createElement('div');
      wrap.appendChild(metaEl);
      doc.write(wrap.innerHTML);
    }
  }

  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;
  }

  win.addEventListener('resize', function () {
    clearTimeout(tid);
    tid = setTimeout(refreshRem, 300);
  }, false);
  win.addEventListener('pageshow', function (e) {
    if (e.persisted) {
      clearTimeout(tid);
      tid = setTimeout(refreshRem, 300);
    }
  }, false);

  if (doc.readyState === 'complete') {
    doc.body.style.fontSize = 12 * dpr + 'px';
  } else {
    doc.addEventListener('DOMContentLoaded', function (e) {
      doc.body.style.fontSize = 12 * dpr + 'px';
    }, false);
  }


  refreshRem();

  flexible.dpr = win.dpr = dpr;
  flexible.refreshRem = refreshRem;
  flexible.rem2px = function (d) {
    var val = parseFloat(d) * this.rem;
    if (typeof d === 'string' && d.match(/rem$/)) {
      val += 'px';
    }
    return val;
  }
  flexible.px2rem = function (d) {
    var val = parseFloat(d) / this.rem;
    if (typeof d === 'string' && d.match(/px$/)) {
      val += 'rem';
    }
    return val;
  }

})(window, window['lib'] || (window['lib'] = {}));

然后在main.js里面引入该文件

import './plugins/rem.js'

这样,我们的工作就完成了。可以直接在css里面写px的绝对值。

详解Vue-cli3.X使用px2rem遇到的问题

详解Vue-cli3.X使用px2rem遇到的问题

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用Mootools获得操作索引的两种方法分享
Dec 12 Javascript
ASP.NET jQuery 实例2 (表单中使用回车在TextBox之间向下移动)
Jan 13 Javascript
jQuery extend 的简单实例
Sep 18 Javascript
用javascript对一个json数组深度赋值示例
Jul 27 Javascript
BootStrap中的table实现数据填充与分页应用小结
May 26 Javascript
JS清除字符串中重复值的实现方法
Aug 03 Javascript
javascript动画系列之模拟滚动条
Dec 13 Javascript
用angular实现多选按钮的全选与反选实例代码
May 23 Javascript
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
Jul 11 Javascript
JS实现的判断方法、变量是否存在功能示例
Mar 28 Javascript
vue中进入详情页记住滚动位置的方法(keep-alive)
Sep 21 Javascript
JS实现计算小于非负数n的素数的数量算法示例
Feb 26 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
Aug 09 #Javascript
小程序Request的另类用法详解
Aug 09 #Javascript
一篇文章弄懂javascript中的执行栈与执行上下文
Aug 09 #Javascript
vue中组件通信的八种方式(值得收藏!)
Aug 09 #Javascript
Vue全局loading及错误提示的思路与实现
Aug 09 #Javascript
使用Vue CLI创建typescript项目的方法
Aug 09 #Javascript
详解vue beforeRouteEnter 异步获取数据给实例问题
Aug 09 #Javascript
You might like
php foreach正序倒序输出示例代码
2014/07/01 PHP
浅谈php使用curl模拟多线程发送请求
2019/03/08 PHP
JS俄罗斯方块,包含完整的设计理念
2010/12/11 Javascript
30分钟就入门的正则表达式基础教程
2013/02/25 Javascript
浅析AngularJS中的生命周期和延迟处理
2015/06/18 Javascript
详解vue2.0组件通信各种情况总结与实例分析
2017/03/22 Javascript
Vue.js常用指令的使用小结
2017/06/23 Javascript
vue.js与element-ui实现菜单树形结构的解决方法
2018/04/21 Javascript
对vue中v-on绑定自定事件的实例讲解
2018/09/06 Javascript
基于vue实现移动端圆形旋钮插件效果
2018/11/28 Javascript
解决layer弹出层的内容页点击按钮跳转到新的页面问题
2019/09/14 Javascript
js实现开关灯效果
2020/03/30 Javascript
vue实现短信验证码登录功能(流程详解)
2019/12/10 Javascript
JSON stringify方法原理及实例解析
2020/10/23 Javascript
[17:00]DOTA2 HEROS教学视频教你分分钟做大人-帕克
2014/06/10 DOTA
[02:09]EHOME夺得首届辉夜杯冠军—现场颁奖仪式
2015/12/28 DOTA
400多行Python代码实现了一个FTP服务器
2012/05/10 Python
使用Python的Scrapy框架编写web爬虫的简单示例
2015/04/17 Python
Python书单 不将就
2017/07/11 Python
python中(str,list,tuple)基础知识汇总
2018/02/20 Python
详解python校验SQL脚本命名规则
2019/03/22 Python
Python3.7 新特性之dataclass装饰器
2019/05/27 Python
详解python如何引用包package
2020/06/07 Python
python如何实现读取并显示图片(不需要图形界面)
2020/07/08 Python
解决python打开https出现certificate verify failed的问题
2020/09/03 Python
python向企业微信发送文字和图片消息的示例
2020/09/28 Python
CSS3制作炫酷的自定义发光文字
2016/03/28 HTML / CSS
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
科沃斯机器人官网商城:Ecovacs
2016/08/29 全球购物
什么是数据抽象
2016/11/26 面试题
前台接待员岗位职责
2014/01/02 职场文书
物流专业大学的自我评价
2014/01/11 职场文书
荷叶圆圆教学反思
2014/02/01 职场文书
趣味运动会活动方案
2014/02/12 职场文书
redis实现排行榜功能
2021/05/24 Redis
python神经网络 使用Keras构建RNN训练
2022/05/04 Python