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 相关文章推荐
prototype 中文参数乱码解决方案
Nov 09 Javascript
javascript Onunload与Onbeforeunload使用小结
Dec 31 Javascript
javascript中var的重要性分析
Feb 11 Javascript
js实现瀑布流的三种方式比较
Jun 28 Javascript
判断数组是否包含某个元素的js函数实现方法
May 19 Javascript
JS查找英文文章中出现频率最高的单词
Mar 20 Javascript
聊聊JavaScript如何实现继承及特点
Apr 07 Javascript
Angular2使用jQuery的方法教程
May 28 jQuery
详解vue-cli3开发Chrome插件实践
May 29 Javascript
这应该是最详细的响应式系统讲解了
Jul 22 Javascript
微信公众号平台接口开发 菜单管理的实现
Aug 14 Javascript
Jquery实现获取子元素的方法分析
Aug 24 jQuery
从零撸一个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
深入理解require与require_once与include以及include_once的区别
2013/06/05 PHP
基于PHPExcel的常用方法总结
2013/06/13 PHP
ThinkPHP查询语句与关联查询用法实例
2014/11/01 PHP
php自定义截取中文字符串-utf8版
2017/02/27 PHP
帮助避免错误的Javascript陷阱清单
2009/05/31 Javascript
Javascript Cookie读写删除操作的函数
2010/03/02 Javascript
JQuery文本框高亮显示插件代码
2011/04/02 Javascript
JavaScript?Apple设备检测示例代码
2013/11/15 Javascript
使用jquery animate创建平滑滚动效果(可以是到顶部、到底部或指定地方)
2014/05/27 Javascript
js使用removeChild方法动态删除div元素
2014/08/01 Javascript
AngularJS控制器继承自另一控制器
2016/05/09 Javascript
jquery插件方式实现table查询功能的简单实例
2016/06/06 Javascript
AngularJS中isolate scope的用法分析
2016/11/22 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
2017/04/18 Javascript
jquery Form轻松实现文件上传
2017/05/24 jQuery
vue axios重复点击取消上一次请求封装的方法
2019/06/19 Javascript
[01:02:17]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG
2014/05/26 DOTA
[02:46]2014DOTA2国际邀请赛 选手为你解读比赛MVP充满梦想
2014/07/09 DOTA
pymssql数据库操作MSSQL2005实例分析
2015/05/25 Python
python字符类型的一些方法小结
2016/05/16 Python
Python处理JSON时的值报错及编码报错的两则解决实录
2016/06/26 Python
Python基于identicon库创建类似Github上用的头像功能
2017/09/25 Python
python 编写简单网页服务器的实例
2018/06/01 Python
pytorch 调整某一维度数据顺序的方法
2018/12/08 Python
Python调用百度根据经纬度查询地址的示例代码
2019/07/07 Python
Flask之pipenv虚拟环境的实现
2019/11/26 Python
Python中使用threading.Event协调线程的运行详解
2020/05/02 Python
使用keras根据层名称来初始化网络
2020/05/21 Python
解决HTML5中滚动到底部的事件问题
2019/08/22 HTML / CSS
Canvas环形饼图与手势控制的实现代码
2019/11/08 HTML / CSS
Theory美国官网:后现代都市风时装品牌
2018/05/09 全球购物
美体小铺奥地利官方网站:The Body Shop奥地利
2019/04/11 全球购物
软件售后服务承诺书
2014/05/21 职场文书
六一儿童节开幕词
2015/01/29 职场文书
CSS3 制作的书本翻页特效
2021/04/13 HTML / CSS
Python测试框架pytest核心库pluggy详解
2022/08/05 Golang