详解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 相关文章推荐
JavaScript的parseInt 进制问题
May 07 Javascript
JavaScript中Cookie操作实例
Jan 09 Javascript
jQuery选择器源码解读(二):select方法
Mar 31 Javascript
Jquery实现顶部弹出框特效
Aug 08 Javascript
js限制文本框的输入内容代码分享(3类)
Aug 20 Javascript
详解ES6中的let命令
Apr 05 Javascript
Node.js环境下Koa2添加travis ci持续集成工具的方法
Jun 19 Javascript
使用Vue开发动态刷新Echarts组件的教程详解
Mar 22 Javascript
基于axios 的responseType类型的设置方法
Oct 29 Javascript
小程序实现可拖动的悬浮按钮
Sep 07 Javascript
vue-amap根据地址回显地图并mark的操作
Nov 03 Javascript
Vue实现跑马灯样式文字横向滚动
Nov 23 Vue.js
微信小程序引入模块中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
PHPMailer安装方法及简单实例
2008/11/25 PHP
PHP第一季视频教程(李炎恢+php100 不断更新)
2011/05/29 PHP
理解Javascript_15_作用域分配与变量访问规则,再送个闭包
2010/10/20 Javascript
Three.js源码阅读笔记(基础的核心Core对象)
2012/12/27 Javascript
阻止子元素继承父元素事件具体思路及实现
2013/05/02 Javascript
Chrome扩展页面动态绑定JS事件提示错误
2014/02/11 Javascript
jquery中使用循环下拉菜单示例代码
2014/09/24 Javascript
论JavaScript模块化编程
2016/03/07 Javascript
js简单判断flash是否加载完成的方法
2016/06/21 Javascript
原生javascript实现的ajax异步封装功能示例
2016/11/03 Javascript
vue-resource 拦截器使用详解
2017/02/21 Javascript
微信小程序表单验证错误提示效果
2017/05/19 Javascript
vue中axios的封装问题(简易版拦截,get,post)
2018/06/15 Javascript
微信小程序实现弹出层效果
2020/05/26 Javascript
vue 中 命名视图的用法实例详解
2019/08/14 Javascript
webpack 动态批量加载文件的实现方法
2020/03/19 Javascript
element 中 el-menu 组件的无限极循环思路代码详解
2020/04/26 Javascript
Python编程中对super函数的正确理解和用法解析
2016/07/02 Python
Python向日志输出中添加上下文信息
2017/05/24 Python
python对配置文件.ini进行增删改查操作的方法示例
2017/07/28 Python
Python使用matplotlib的pie函数绘制饼状图功能示例
2018/01/08 Python
Centos下实现安装Python3.6和Python2共存
2018/08/15 Python
python pcm音频添加头转成Wav格式文件的方法
2019/01/09 Python
自适应线性神经网络Adaline的python实现详解
2019/09/30 Python
python matplotlib模块基本图形绘制方法小结【直线,曲线,直方图,饼图等】
2020/04/26 Python
python实现从ftp上下载文件的实例方法
2020/07/19 Python
python实现简单的学生管理系统
2021/02/22 Python
IE支持HTML5的解决方法
2009/10/20 HTML / CSS
美国殿堂级滑板、冲浪、滑雪服装品牌:Volcom(钻石)
2017/04/20 全球购物
iHerb中文官网:维生素、保健品和健康产品
2018/11/01 全球购物
C和C++经典笔试题附答案解析
2014/08/18 面试题
企业给企业的表扬信
2014/01/13 职场文书
《难忘的泼水节》教学反思
2014/02/27 职场文书
爱与责任师德演讲稿
2014/08/26 职场文书
化工见习报告范文
2014/10/31 职场文书
Python基础详解之邮件处理
2021/04/28 Python