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 相关文章推荐
对textarea框的代码调试,而且功能上使用非常方便,酷
Jun 30 Javascript
使用户点击后退按钮使效三行代码
Jul 07 Javascript
基于JQuery的Pager分页器实现代码
Jul 17 Javascript
21个值得收藏的Javascript技巧
Feb 04 Javascript
Jquery Ajax方法传值到action的方法
May 11 Javascript
理解javascript中DOM事件
Dec 25 Javascript
jQuery输入框密码的显示隐藏【代码分享】
Apr 29 jQuery
webstorm添加*.vue文件支持
May 08 Javascript
基于Vue实现微信小程序的图文编辑器
Jul 25 Javascript
微信小程序模板template简单用法示例
Dec 04 Javascript
解决layui动态添加的元素click等事件触发不了的问题
Sep 20 Javascript
微信小程序 根据不同用户切换不同TabBar
Apr 21 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
如何去掉文章里的 html 语法
2006/10/09 PHP
php设计模式 Facade(外观模式)
2011/06/26 PHP
php动态实现表格跨行跨列实现代码
2012/11/06 PHP
discuz图片顺序混乱解决方案
2015/07/29 PHP
Symfony的安装和配置方法
2016/03/17 PHP
thinkPHP5.0框架URL访问方法详解
2017/03/18 PHP
PHP fopen函数用法实例讲解
2019/02/15 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
xmlHTTP实例
2006/10/24 Javascript
jQuery+ajax实现鼠标单击修改内容的思路
2014/06/29 Javascript
nodejs中使用多线程编程的方法实例
2015/03/24 NodeJs
基于jQuery1.9版本如何判断浏览器版本类型
2016/01/12 Javascript
JS及JQuery对Html内容编码,Html转义
2017/02/17 Javascript
Vue2递归组件实现树形菜单
2017/04/10 Javascript
AngularJS 验证码60秒倒计时功能的实现
2017/06/05 Javascript
webpack构建vue项目的详细教程(配置篇)
2017/07/17 Javascript
Vue实现Layui的集成方法步骤
2020/04/10 Javascript
[49:15]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第二场 1月19日
2021/03/11 DOTA
python分布式环境下的限流器的示例
2017/10/26 Python
K-means聚类算法介绍与利用python实现的代码示例
2017/11/13 Python
python+VTK环境搭建及第一个简单程序代码
2017/12/13 Python
python selenium 对浏览器标签页进行关闭和切换的方法
2018/05/21 Python
详解Python3网络爬虫(二):利用urllib.urlopen向有道翻译发送数据获得翻译结果
2019/05/07 Python
Python 实现简单的客户端认证
2020/07/29 Python
Pycharm无法打开双击没反应的问题及解决方案
2020/08/17 Python
html Table 表头固定的实现
2019/01/22 HTML / CSS
html5如何在Canvas中实现自定义路径动画示例
2017/09/18 HTML / CSS
日本热销NO.1胶原蛋白冻:Aishitoto爱希特多
2019/06/20 全球购物
学校联谊活动方案
2014/02/15 职场文书
读书演讲主持词
2014/03/18 职场文书
事业单位竞聘上岗实施方案
2014/03/28 职场文书
口才训练演讲稿范文
2014/09/16 职场文书
市委召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
2014年党务工作总结
2014/11/25 职场文书
2016新年致辞
2015/08/01 职场文书
Go 语言结构实例分析
2021/07/04 Golang