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 相关文章推荐
csdn 批量接受好友邀请
Feb 19 Javascript
js css样式操作代码(批量操作)
Oct 09 Javascript
基于Jquery的回车成tab焦点切换效果代码(Enter To Tab )
Nov 14 Javascript
基于jquery的不规则矩形的排列实现代码
Apr 16 Javascript
原生javascript实现的分页插件pagenav
Aug 28 Javascript
javascript弹出页面回传值的方法
Jan 28 Javascript
深入浅出理解javaScript原型链
May 09 Javascript
jQuery实现Email邮箱地址自动补全功能代码
Nov 03 Javascript
微信小程序左滑删除效果的实现代码
Feb 20 Javascript
微信小程序将字符串生成二维码图片的操作方法
Jul 17 Javascript
js正则取值的结果数组调试方法
Oct 10 Javascript
详解Vue中使用Axios拦截器
Apr 22 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
人工智能开始玩《星际争霸2》 你的操作跟得上吗?
2017/08/11 星际争霸
SSO单点登录的PHP实现方法(Laravel框架)
2016/03/23 PHP
PHP中的多种加密技术及代码示例解析
2016/10/20 PHP
PHP实现Redis单据锁以及防止并发重复写入
2018/04/10 PHP
表单填写时用回车代替TAB的实现方法
2007/10/09 Javascript
JS限制Textarea文本域字符个数的具体实现
2013/08/02 Javascript
jquery实现页面关键词高亮显示的方法
2015/03/12 Javascript
详解JavaScript中this关键字的用法
2016/05/26 Javascript
纯css下拉菜单 无需js
2016/08/15 Javascript
BootStrap Validator对于隐藏域验证和程序赋值即时验证的问题浅析
2016/12/01 Javascript
jquery实现的table排序功能示例
2017/03/10 Javascript
Vue响应式原理详解
2017/04/18 Javascript
JavaScript 日期时间选择器一些小结
2018/04/02 Javascript
layui当点击文本框时弹出选择框,显示选择内容的例子
2019/09/02 Javascript
解决layer.confirm快速点击会重复触发事件的问题
2019/09/23 Javascript
Vue数字输入框组件示例代码详解
2020/01/15 Javascript
vue项目中使用vue-layer弹框插件的方法
2020/03/11 Javascript
Angular进行简单单元测试的实现方法实例
2020/08/16 Javascript
[02:27]《DAC最前线》之附加赛征程
2015/01/29 DOTA
python脚本实现查找webshell的方法
2014/07/31 Python
Python配置mysql的教程(推荐)
2017/10/13 Python
python脚本作为Windows服务启动代码详解
2018/02/11 Python
Tensorflow 实现修改张量特定元素的值方法
2018/07/30 Python
Python Scapy随心所欲研究TCP协议栈
2018/11/20 Python
pycharm中import呈现灰色原因的解决方法
2020/03/04 Python
美国首屈一指的礼品篮供应商:GiftTree
2018/01/06 全球购物
预备党员思想汇报
2014/01/08 职场文书
会计专业自我评价
2014/02/12 职场文书
安全生产一岗双责责任书
2014/07/28 职场文书
乡村教师党员四风问题对照检查材料思想汇报
2014/10/08 职场文书
2014年挂职干部工作总结
2014/12/06 职场文书
2015年安全保卫工作总结
2015/05/14 职场文书
在校生证明
2015/06/17 职场文书
php 获取音视频时长,PHP 利用getid3 获取音频文件时长等数据
2021/04/01 PHP
Java常用工具类汇总 附示例代码
2021/06/26 Java/Android
springboot 全局异常处理和统一响应对象的处理方式
2022/06/28 Java/Android