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 相关文章推荐
jquery map方法使用示例
Apr 23 Javascript
jQuery中removeProp()方法用法实例
Jan 05 Javascript
解决bootstrap中modal遇到Esc键无法关闭页面
Mar 09 Javascript
JavaScript代码判断点击第几个按钮
Dec 13 Javascript
jquery实现点击弹出可放大居中及关闭的对话框(附demo源码下载)
May 10 Javascript
js手动播放图片实现图片轮播效果
Sep 17 Javascript
Cpage.js给组件绑定事件的实现代码
Aug 31 Javascript
Angular实现搜索框及价格上下限功能
Jan 19 Javascript
微信小程序Flex布局用法深入浅出分析
Apr 25 Javascript
js计算两个时间差 天 时 分 秒 毫秒的代码
May 21 Javascript
vue 实现强制类型转换 数字类型转为字符串
Nov 07 Javascript
微信小程序canvas开发水果老虎机的思路详解
Feb 07 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
带你了解PHP7 性能翻倍的关键
2015/11/19 PHP
thinkphp框架实现数据添加和显示功能
2016/06/29 PHP
window.open的功能全解析
2006/10/10 Javascript
js判断客户端是iOS还是Android等移动终端的方法
2013/12/11 Javascript
使用js Math.random()函数生成n到m间的随机数字
2014/10/09 Javascript
JavaScript中的toUTCString()方法使用详解
2015/06/12 Javascript
Position属性之relative用法
2015/12/14 Javascript
jquery ajax局部加载方法详解(实现代码)
2016/05/12 Javascript
深入理解Angularjs向指令传递数据双向绑定机制
2016/12/31 Javascript
jQuery Validate 数组 全部验证问题
2017/01/12 Javascript
JS动态添加元素及绑定事件造成程序重复执行解决
2017/12/07 Javascript
vue按需加载组件webpack require.ensure的方法
2017/12/13 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
python从入门到精通(DAY 3)
2015/12/20 Python
全面理解Python中self的用法
2016/06/04 Python
深入了解Python中pop和remove的使用方法
2018/01/09 Python
Python 生成 -1~1 之间的随机数矩阵方法
2018/08/04 Python
Python3爬楼梯算法示例
2019/03/04 Python
pandas删除指定行详解
2019/04/04 Python
Django admin.py 在修改/添加表单界面显示额外字段的方法
2019/08/22 Python
pygame实现打字游戏
2021/02/19 Python
python科学计算之numpy——ufunc函数用法
2019/11/25 Python
Python字节单位转换实例
2019/12/05 Python
Pytorch 定义MyDatasets实现多通道分别输入不同数据方式
2020/01/15 Python
python实现移动木板小游戏
2020/10/09 Python
canvas如何绘制钟表的方法
2017/12/13 HTML / CSS
菲律宾领先的在线时尚商店:Zalora菲律宾
2018/02/08 全球购物
会话Bean的种类
2013/11/07 面试题
Unix里面如何在后台运行程序
2016/10/14 面试题
经典婚礼主持词
2014/03/13 职场文书
优秀中职教师事迹材料
2014/08/26 职场文书
二年级语文上册复习计划
2015/01/19 职场文书
学校青年志愿者活动总结
2015/05/06 职场文书
冰雪公主观后感
2015/06/16 职场文书
opencv用VS2013调试时用Image Watch插件查看图片
2021/07/26 Python
Android实现获取短信验证码并自动填充
2023/05/21 Java/Android