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 相关文章推荐
javascript下查找父节点的简单方法
Aug 13 Javascript
javascript 树控件 比较好用
Jun 11 Javascript
HTML页面滚动时获取离页面顶部的距离2种实现方法
Sep 05 Javascript
JavaScript中的连字符详解
Nov 28 Javascript
JavaScript中的toLocaleLowerCase()方法使用详解
Jun 06 Javascript
使用requestAnimationFrame实现js动画性能好
Aug 06 Javascript
JS模仿编辑器实时改变文本框宽度和高度大小的方法
Aug 17 Javascript
AngularJS directive返回对象属性详解
Mar 28 Javascript
jQuery Mobile和HTML5开发App推广注册页
Nov 07 Javascript
浅谈通过JS拦截 pushState和replaceState事件
Jul 21 Javascript
javascript字体颜色控件的开发 JS实现字体控制
Nov 27 Javascript
vue中的.$mount('#app')手动挂载操作
Sep 02 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 clearstatcache()函数详解
2010/03/02 PHP
Window下PHP三种运行方式图文详解
2013/06/11 PHP
PHP上传文件参考配置大文件上传
2015/12/16 PHP
PHP指定截取字符串中的中英文或数字字符的实例分享
2016/03/18 PHP
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
jQuery each()小议
2010/03/18 Javascript
canvas绘制表盘时钟
2017/01/23 Javascript
js仿小米手机上下滑动效果
2017/02/05 Javascript
使用get方式提交表单在地址栏里面不显示提交信息
2017/02/21 Javascript
详解vee-validate的使用个人小结
2017/06/07 Javascript
jQuery实现动态给table赋值的方法示例
2017/07/04 jQuery
VUE2 前端实现 静态二级省市联动选择select的示例
2018/02/09 Javascript
vue利用axios来完成数据的交互
2018/03/23 Javascript
Vue组件创建和传值的方法
2018/08/17 Javascript
微信小程序开发中var that =this的用法详解
2020/01/18 Javascript
JavaScript设计模型Iterator实例解析
2020/01/22 Javascript
JavaScript队列结构Queue实现过程解析
2020/03/07 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
2020/05/06 Javascript
解决vue项目router切换太慢问题
2020/07/19 Javascript
javascript实现京东登录显示隐藏密码
2020/08/02 Javascript
[01:18:21]EG vs TNC Supermajor小组赛B组败者组第一轮 BO3 第一场 6.2
2018/06/03 DOTA
django使用xlwt导出excel文件实例代码
2018/02/06 Python
python提取图像的名字*.jpg到txt文本的方法
2018/05/10 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
Python ORM编程基础示例
2020/02/02 Python
HTML5 Web存储方式的localStorage和sessionStorage进行数据本地存储案例应用
2012/12/09 HTML / CSS
AOP的定义以及作用
2013/09/08 面试题
编码转换,怎样实现将GB2312编码的字符串转换为ISO-8859-1编码的字符串
2014/01/07 面试题
行政文员岗位职责
2013/11/08 职场文书
小饰品店的创业计划书范文
2013/12/28 职场文书
《果园机器人》教学反思
2014/04/13 职场文书
学校募捐倡议书
2014/05/14 职场文书
英语演讲开场白
2015/05/29 职场文书
2015年入党积极分子培养考察意见
2015/08/12 职场文书
Python机器学习实战之k-近邻算法的实现
2021/11/27 Python
Linux服务器离线安装 nginx的详细步骤
2022/06/16 Servers