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的eval JSON object问题
Nov 15 Javascript
javascript中的prototype属性使用说明(函数功能扩展)
Aug 16 Javascript
利用jQuery操作对象数组的实现代码
Apr 27 Javascript
浅谈javascript中的作用域
Apr 07 Javascript
JavaScript中的匀速运动和变速(缓冲)运动详细介绍
Nov 11 Javascript
基于JavaScript实现弹出框效果
Feb 19 Javascript
学习使用jQuery表单验证插件和日历插件
Feb 13 Javascript
vue router学习之动态路由和嵌套路由详解
Sep 21 Javascript
详解vue.js数据传递以及数据分发slot
Jan 20 Javascript
解决vue cli使用typescript后打包巨慢的问题
Sep 30 Javascript
vue改变循环遍历后的数据实例
Nov 07 Javascript
vue3自定义dialog、modal组件的方法
Jan 04 Vue.js
从零撸一个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 和 MySQL 时区的一点总结
2008/03/26 PHP
PHP中使用asort进行中文排序失效的问题处理
2014/08/18 PHP
PHP实现的简单日历类
2014/11/29 PHP
php模拟服务器实现autoindex效果的方法
2015/03/10 PHP
PHP join()函数用法与实例讲解
2019/03/11 PHP
Laravel 实现在Blade模版中使用全局变量代替路径的例子
2019/10/22 PHP
JavaScript 自动分号插入(JavaScript synat:auto semicolon insertion)
2009/11/04 Javascript
jquery实现顶部向右伸缩的导航区域代码
2015/09/02 Javascript
详解javascript中原始数据类型Null和Undefined
2015/12/17 Javascript
AngularJS中实现显示或隐藏动画效果的方式总结
2015/12/31 Javascript
Bootstrap布局之栅格系统详解
2016/06/13 Javascript
jQuery插件zTree实现的基本树与节点获取操作示例
2017/03/08 Javascript
Vue常用指令V-model用法
2017/03/08 Javascript
Angular中的$watch方法详解
2017/09/18 Javascript
Ionic学习日记实现验证码倒计时
2018/02/08 Javascript
javascript中call()、apply()的区别
2019/03/21 Javascript
webpack proxy 使用(代理的使用)
2020/01/10 Javascript
javascript 设计模式之享元模式原理与应用详解
2020/04/08 Javascript
javascript 使用sleep函数的常见方法详解
2020/04/26 Javascript
python中使用OpenCV进行人脸检测的例子
2014/04/18 Python
TF-IDF与余弦相似性的应用(一) 自动提取关键词
2017/12/21 Python
Python基于pycrypto实现的AES加密和解密算法示例
2018/04/10 Python
Python中的取模运算方法
2018/11/10 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
2018/12/10 Python
解决nohup执行python程序log文件写入不及时的问题
2019/01/14 Python
python安装pil库方法及代码
2019/06/25 Python
检测tensorflow是否使用gpu进行计算的方式
2020/02/03 Python
如何实现在jupyter notebook中播放视频(不停地展示图片)
2020/04/23 Python
Python 在 VSCode 中使用 IPython Kernel 的方法详解
2020/09/05 Python
TripAdvisor斯洛伐克:阅读评论、比较价格和酒店预订
2018/04/25 全球购物
Web Service面试题:如何搭建Axis2的开发环境
2012/06/20 面试题
公安局班子个人对照检查材料思想汇报
2014/10/09 职场文书
学生会感恩节活动方案
2014/10/11 职场文书
2016年幼儿园教师师德承诺书
2016/03/25 职场文书
学习计划是什么
2019/04/30 职场文书
使用Djongo模块在Django中使用MongoDB数据库
2021/06/20 Python