详解Vue-cli3.X使用px2rem遇到的问题


Posted in Javascript onAugust 09, 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使用px2rem遇到的问题

详解Vue-cli3.X使用px2rem遇到的问题

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
强悍无比的WEB开发好助手FireBug(Firefox Plugin)
Jan 16 Javascript
javascript getElementsByClassName函数
Apr 01 Javascript
网页图片延时加载的js代码
Apr 22 Javascript
javascript 兼容所有浏览器的DOM扩展功能
Aug 01 Javascript
JavaScript中OnLoad几种使用方法
Dec 15 Javascript
JS动态创建Table,Tr,Td并赋值的具体实现
Jul 05 Javascript
使用javascript实现判断当前浏览器
Apr 14 Javascript
jQuery实现带滑动条的菜单效果代码
Aug 26 Javascript
Vue学习笔记进阶篇之vue-router安装及使用方法
Jul 19 Javascript
vue实现的组件兄弟间通信功能示例
Dec 04 Javascript
详解小程序如何避免多次点击,重复触发事件
Apr 08 Javascript
如何利用React实现图片识别App
Feb 18 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
Aug 09 #Javascript
小程序Request的另类用法详解
Aug 09 #Javascript
一篇文章弄懂javascript中的执行栈与执行上下文
Aug 09 #Javascript
vue中组件通信的八种方式(值得收藏!)
Aug 09 #Javascript
Vue全局loading及错误提示的思路与实现
Aug 09 #Javascript
使用Vue CLI创建typescript项目的方法
Aug 09 #Javascript
详解vue beforeRouteEnter 异步获取数据给实例问题
Aug 09 #Javascript
You might like
PHP的面向对象编程
2006/10/09 PHP
第九节--绑定
2006/11/16 PHP
PHP调用VC编写的COM组件实例
2014/03/29 PHP
php利用scws实现mysql全文搜索功能的方法
2014/12/25 PHP
thinkphp在php7环境下提示Cannot use ‘String’ as class name as it is reserved的解决方法
2016/09/30 PHP
Zend Framework数据库操作方法实例总结
2016/12/11 PHP
PHP小白必须要知道的php基础知识(超实用)
2017/10/10 PHP
php实现支付宝当面付(扫码支付)功能
2018/05/30 PHP
JQuery 无废话系列教程(一) jquery入门 [推荐]
2009/06/23 Javascript
从零学jquery之如何使用回调函数
2014/05/16 Javascript
node.js中的fs.writeFile方法使用说明
2014/12/14 Javascript
jQuery中ajax的load()与post()方法实例详解
2016/01/05 Javascript
JavaScript验证知识整理
2017/03/24 Javascript
js实现动态改变radio状态的方法
2018/02/28 Javascript
JS实现移动端触屏拖拽功能
2018/07/31 Javascript
关于vue 结合原生js 解决echarts resize问题
2020/07/26 Javascript
Python实现的检测web服务器健康状况的小程序
2014/09/17 Python
Python IDE PyCharm的基本快捷键和配置简介
2015/11/04 Python
python非递归全排列实现方法
2017/04/10 Python
python学习笔记之列表(list)与元组(tuple)详解
2017/11/23 Python
简述Python2与Python3的不同点
2018/01/21 Python
dataframe设置两个条件取值的实例
2018/04/12 Python
python随机在一张图像上截取任意大小图片的方法
2019/01/24 Python
Python3分析处理声音数据的例子
2019/08/27 Python
pytorch中图像的数据格式实例
2020/02/11 Python
Python自动登录QQ的实现示例
2020/08/28 Python
香港个人化生活购物网站:Ballyhoo Limited
2016/09/10 全球购物
政风行风自查自纠报告
2014/10/21 职场文书
出差报告范文
2014/11/06 职场文书
拾金不昧表扬信
2015/01/16 职场文书
金秋助学感谢信
2015/01/21 职场文书
周恩来的四个昼夜观后感
2015/06/03 职场文书
格列佛游记读书笔记
2015/06/30 职场文书
开网店计划分析
2019/07/30 职场文书
Django对接elasticsearch实现全文检索的示例代码
2021/08/02 Python
Win11 Beta 预览版 22621.575 和 22622.575更新补丁KB5016694发布(附更新内容大全)
2022/08/14 数码科技