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 相关文章推荐
$.format,jquery.format 使用说明
Jul 13 Javascript
文本有关的样式和jQuery求对象的高宽问题分别说明
Aug 30 Javascript
浏览器兼容console对象的简要解决方案分享
Oct 24 Javascript
jquery 删除字符串最后一个字符的方法解析
Feb 11 Javascript
javascript实现dom元素可拖动
Mar 21 Javascript
jQuery弹出层插件popShow用法示例
Jan 23 Javascript
angularjs实现多张图片上传并预览功能
Feb 24 Javascript
浅谈regExp的test方法取得的值变化的原因及处理方法
Mar 01 Javascript
JavaScript实现京东购物放大镜和选项卡效果的方法分析
Jul 05 Javascript
vue操作下拉选择器获取选择的数据的id方法
Aug 24 Javascript
Vue开发中遇到的跨域问题及解决方法
Feb 11 Javascript
小程序组件传值和引入sass的方法(使用vant Weapp组件库)
Nov 24 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
php实现读取内存顺序号
2015/03/29 PHP
JSON两种结构之对象和数组的理解
2016/07/19 PHP
JavaScript 基础知识 被自己遗忘的
2009/10/15 Javascript
js split 的用法和定义 js split分割字符串成数组的实例代码
2012/05/13 Javascript
关于js new Date() 出现NaN 的分析
2012/10/23 Javascript
返回上一页并自动刷新的JavaScript代码
2014/02/19 Javascript
javascript中的事件代理初探
2014/03/08 Javascript
javascript的tab切换原理与效果实现方法
2015/01/10 Javascript
JS返回iframe中frameBorder属性值的方法
2015/04/01 Javascript
JS实现滑动菜单效果代码(包括Tab,选项卡,横向等效果)
2015/09/24 Javascript
详解JavaScript权威指南之对象
2016/09/27 Javascript
jQuery中get方法用法分析
2016/12/07 Javascript
BootStrap3使用错误记录及解决办法
2016/12/22 Javascript
详解node如何让一个端口同时支持https与http
2017/07/04 Javascript
JavaScript正则表达式和级联效果
2017/09/14 Javascript
vue组件间通信子与父详解(二)
2017/11/07 Javascript
js时间戳与日期格式之间转换详解
2017/12/11 Javascript
p5.js入门教程之小球动画示例代码
2018/03/15 Javascript
node实现基于token的身份验证
2018/04/09 Javascript
Vue 动态路由的实现及 Springsecurity 按钮级别的权限控制
2019/09/05 Javascript
Python 可爱的大小写
2008/09/06 Python
Python中max函数用法实例分析
2015/07/17 Python
简述Python中的进程、线程、协程
2016/03/18 Python
详解Python中的__getitem__方法与slice对象的切片操作
2016/06/27 Python
pip安装Python库时遇到的问题及解决方法
2017/11/23 Python
Python实现获取邮箱内容并解析的方法示例
2018/06/16 Python
django缓存配置的几种方法详解
2018/07/16 Python
基于DataFrame改变列类型的方法
2018/07/25 Python
python SocketServer源码深入解读
2019/09/17 Python
使用python将最新的测试报告以附件的形式发到指定邮箱
2019/09/20 Python
使用HTML5 Canvas绘制圆角矩形及相关的一些应用举例
2016/03/22 HTML / CSS
员工考核评语大全
2014/04/26 职场文书
中华美德颂演讲稿
2014/05/20 职场文书
授权委托书(法人单位用)
2014/09/29 职场文书
如何做好工作总结!
2019/04/10 职场文书
SpringBoot集成Redis,并自定义对象序列化操作
2021/06/22 Java/Android