Vue-cli3.X使用px2 rem遇到的问题及解决方法


Posted in Javascript onAugust 08, 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使用px2 rem遇到的问题及解决方法

Vue-cli3.X使用px2 rem遇到的问题及解决方法

总结

以上所述是小编给大家介绍的Vue-cli3.X使用px2 rem遇到的问题及解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
asp.net 30分钟掌握无刷新 Repeater
Sep 16 Javascript
js制作的鼠标悬浮时产生的下拉框效果
Oct 27 Javascript
基于dom编程中 动态创建与删除元素的使用
Apr 17 Javascript
JQuery为textarea添加maxlength属性并且兼容IE
Apr 25 Javascript
js抽奖实现随机抽奖代码效果
Dec 02 Javascript
js简单网速测试方法完整实例
Dec 15 Javascript
Bootstrap基本组件学习笔记之缩略图(13)
Dec 08 Javascript
Vue实现双向绑定的方法
Dec 22 Javascript
详解JavaScript常量定义
Jan 03 Javascript
在iframe中使bootstrap的模态框在父页面弹出问题
Aug 07 Javascript
vue如何引入sass全局变量
Jun 28 Javascript
Vue中nprogress页面加载进度条的方法实现
Nov 13 Javascript
从零撸一个pc端vue的ui组件库( 计数器组件 )
Aug 08 #Javascript
非常实用的jQuery代码段集锦【检测浏览器、滚动、复制、淡入淡出等】
Aug 08 #jQuery
微信小程序嵌入腾讯视频源过程详解
Aug 08 #Javascript
17道题让你彻底理解JS中的类型转换
Aug 08 #Javascript
微信小程序bindtap事件与冒泡阻止详解
Aug 08 #Javascript
vue2 拖动排序 vuedraggable组件的实现
Aug 08 #Javascript
React+TypeScript+webpack4多入口配置详解
Aug 08 #Javascript
You might like
C#静态方法与非静态方法实例分析
2014/09/22 PHP
PHP查询快递信息的方法
2015/03/07 PHP
PHP提高编程效率的20个要点
2015/09/23 PHP
php while循环控制的简单实例
2016/05/30 PHP
Alliance vs Liquid BO3 第三场2.13
2021/03/10 DOTA
Javascript调试工具(下载)
2007/01/09 Javascript
Extjs4中Form的使用之本地hiddenfield
2013/11/26 Javascript
Jquery的Tabs内容轮换效果实现代码,几行搞定
2014/02/12 Javascript
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
JavaScript过滤字符串中的中文与空格方法汇总
2016/03/07 Javascript
jQueryUI DatePicker 添加时分秒
2016/06/04 Javascript
利用策略模式与装饰模式扩展JavaScript表单验证功能
2017/02/14 Javascript
深入理解Node.js中的进程管理
2017/03/13 Javascript
vue2.0 datepicker使用方法
2018/02/04 Javascript
解决koa2 ctx.render is not a function报错问题
2018/08/07 Javascript
微信小程序自定义波浪组件使用方法详解
2019/09/21 Javascript
[02:31]DOTA2帕克 英雄基础教程
2013/11/26 DOTA
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
python 默认参数问题的陷阱
2016/02/29 Python
django中SMTP发送邮件配置详解
2019/07/19 Python
flask的orm框架SQLAlchemy查询实现解析
2019/12/12 Python
解决python -m pip install --upgrade pip 升级不成功问题
2020/03/05 Python
scrapy爬虫:scrapy.FormRequest中formdata参数详解
2020/04/30 Python
基于python 取余问题(%)详解
2020/06/03 Python
五分钟学会HTML5的WebSocket协议
2019/11/22 HTML / CSS
英国家庭珠宝商:T. H. Baker
2018/02/08 全球购物
护理专业学生的求职信范文
2013/12/11 职场文书
师德个人剖析材料
2014/02/02 职场文书
优秀老员工获奖感言
2014/02/15 职场文书
3的组成教学反思
2014/04/30 职场文书
毕业典礼演讲稿
2014/05/13 职场文书
庆元旦演讲稿
2014/09/15 职场文书
2017大学生寒假社会实践心得体会
2016/01/14 职场文书
企业内部管理控制:采购授权审批制度范本
2020/01/19 职场文书
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
Python编程中内置的NotImplemented类型的用法
2022/03/23 Python