详解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 相关文章推荐
js实现iframe动态调整高度的代码
Jan 06 Javascript
用json方式实现在 js 中建立一个map
May 02 Javascript
jQuery实现的向下图文信息滚动效果
May 03 Javascript
详解AngularJS中的表达式使用
Jun 16 Javascript
基于Css3和JQuery实现打字机效果
Aug 11 Javascript
js实现简单计算器
Nov 22 Javascript
ECMAscript 变量作用域总结概括
Aug 18 Javascript
微信小程序登录换取token的教程
May 31 Javascript
Vue自定义全局Toast和Loading的实例详解
Apr 18 Javascript
使用JavaScript实现网页秒表功能(含开始、暂停、继续、重置功能)
Jun 05 Javascript
Jquery使用each函数实现遍历及数组处理
Jul 14 jQuery
jquery实现拖拽添加元素功能
Dec 01 jQuery
微信小程序引入模块中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 simplexmlElement操作xml的命名空间实现代码
2011/01/04 PHP
php类常量的使用详解
2013/06/08 PHP
Javascript 对象的解释
2008/11/24 Javascript
JavaScript中的作用域链和闭包
2012/06/30 Javascript
uploadify在Firefox下丢失session问题的解决方法
2013/08/07 Javascript
javascript实现禁止复制网页内容
2014/12/16 Javascript
jquery无限级联下拉菜单简单实例演示
2015/11/23 Javascript
jquery trigger函数执行两次的解决方法
2016/02/29 Javascript
浅谈js中的引用和复制(传值和传址)
2016/09/18 Javascript
JQuery学习总结【一】
2016/12/01 Javascript
jQuery使用Layer弹出层插件闪退问题
2016/12/22 Javascript
Vue.js通用应用框架-Nuxt.js的上手教程
2017/12/25 Javascript
解决layui 复选框等内置控件不显示的问题
2018/08/14 Javascript
vue 获取url参数、get参数返回数组的操作
2020/11/12 Javascript
python实现异步回调机制代码分享
2014/01/10 Python
Java多线程编程中ThreadLocal类的用法及深入
2016/06/21 Python
Python元组常见操作示例
2019/02/19 Python
python根据多个文件名批量查找文件
2019/08/13 Python
Python操作Mongodb数据库的方法小结
2019/09/10 Python
用python画一只可爱的皮卡丘实例
2019/11/21 Python
python连接打印机实现打印文档、图片、pdf文件等功能
2020/02/07 Python
HTML5中判断横屏竖屏的方法(移动端)
2016/08/04 HTML / CSS
微软瑞士官方网站:Microsoft瑞士
2018/04/20 全球购物
意大利婴儿产品网上商店:Mukako
2018/10/14 全球购物
opencv实现图像几何变换
2021/03/24 Python
写好求职应聘自荐信的三部曲
2013/09/21 职场文书
如何做好总经理助理
2013/11/12 职场文书
歌唱比赛获奖感言
2014/01/21 职场文书
物理专业大学生职业生涯规划书
2014/02/07 职场文书
能源工程专业应届生求职信
2014/03/01 职场文书
怎样填写就业意向
2014/04/02 职场文书
六一儿童节演讲稿
2014/05/23 职场文书
优秀学生干部先进事迹材料
2014/05/26 职场文书
Linux安装Nginx步骤详解
2021/03/31 Servers
Mysql实现主从配置和多主多从配置
2021/06/02 MySQL
mysql主从复制的实现步骤
2021/10/24 MySQL