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 框架使用教程 AJAX篇
Oct 11 Javascript
JavaScript中的稀疏数组与密集数组[译]
Sep 17 Javascript
jquery offset函数应用实例
Nov 14 Javascript
javascript与有限状态机详解
May 08 Javascript
极易被忽视的javascript面试题七问七答
Feb 15 Javascript
浅谈js中对象的使用
Aug 11 Javascript
jQuery动态创建元素以及追加节点的实现方法
Oct 20 Javascript
详解用node编写自己的cli工具
May 23 Javascript
学习使用ExpressJS 4.0中的新Router的用法
Nov 06 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
May 08 Javascript
vue draggable resizable 实现可拖拽缩放的组件功能
Jul 15 Javascript
JQuery实现折叠式菜单的详细代码
Jun 03 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
php下封装较好的数字分页方法
2010/11/23 PHP
php 注册时输入信息验证器的实现详解
2013/07/05 PHP
PHP上传文件参考配置大文件上传
2015/12/16 PHP
php解析xml 的四种简单方法(附实例)
2016/07/11 PHP
PHP编程实现计算抽奖概率算法完整实例
2017/08/09 PHP
php中通用的excel导出方法实例
2017/12/30 PHP
PHP缓存工具XCache安装与使用方法详解
2018/04/09 PHP
THINKPHP5分页数据对象处理过程解析
2020/10/28 PHP
jQuery 使用手册(七)
2009/09/23 Javascript
初识JQuery 实例一(first)
2011/03/16 Javascript
JQuery操作Select的Options的Bug(IE8兼容性视图模式)
2013/04/21 Javascript
JavaScript中document.forms[0]与getElementByName区别
2015/01/21 Javascript
JavaScript实现图片轮播组件代码示例
2016/11/22 Javascript
详解Node.js实现301、302重定向服务
2017/04/07 Javascript
浅谈node中的cluster集群
2018/06/02 Javascript
Vue + Elementui实现多标签页共存的方法
2019/06/12 Javascript
[04:09]2014DOTA2国际邀请赛Ti西雅图 历届冠军相继出局 BBC综述今日比赛
2014/07/20 DOTA
[40:53]完美世界DOTA2联赛PWL S3 Magma vs DLG 第二场 12.18
2020/12/20 DOTA
Python获取航线信息并且制作成图的讲解
2019/01/03 Python
解决Python3 被PHP程序调用执行返回乱码的问题
2019/02/16 Python
Python3模拟curl发送post请求操作示例
2019/05/03 Python
python多进程并发demo实例解析
2019/12/13 Python
Python requests获取网页常用方法解析
2020/02/20 Python
numpy矩阵数值太多不能全部显示的解决
2020/05/14 Python
如何理解python中数字列表
2020/05/29 Python
在tensorflow下利用plt画论文中loss,acc等曲线图实例
2020/06/15 Python
基于python tkinter的点名小程序功能的实例代码
2020/08/22 Python
基于Python爬取股票数据过程详解
2020/10/21 Python
美国隐形眼镜网:Major Lens
2018/02/09 全球购物
阿根廷票务网站:StubHub阿根廷
2018/04/13 全球购物
保险公司演讲稿
2014/09/02 职场文书
2014派出所所长群众路线对照检查材料思想汇报
2014/09/18 职场文书
财务人员个人工作总结
2015/02/27 职场文书
中国古代史学名著《战国策》概述
2019/08/09 职场文书
六年级情感作文之500字
2019/10/23 职场文书
python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法
2021/06/05 Python