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 TextArea动态显示剩余字符
Oct 22 Javascript
javascript parseInt 函数分析(转)
Mar 21 Javascript
javascript获取select的当前值示例代码(兼容IE/Firefox/Opera/Chrome)
Dec 17 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
Nov 02 Javascript
微信小程序 PHP后端form表单提交实例详解
Jan 12 Javascript
微信小程序 仿美团分类菜单 swiper分类菜单
Apr 12 Javascript
原JS实现banner图的常用功能
Jun 12 Javascript
jQuery实现所有验证通过方可提交的表单验证
Nov 21 jQuery
JS计算输出100元钱买100只鸡问题的解决方法
Jan 04 Javascript
Vue中使用sass实现换肤功能
Sep 07 Javascript
写gulp遇到的ES6问题详解
Dec 03 Javascript
JavaScript中判断为整数的多种方式及保留两位小数的方法
Sep 09 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
CodeIgniter实现更改view文件夹路径的方法
2014/07/04 PHP
PHP生成不重复标识符的方法
2014/11/21 PHP
Laravel重写用户登录简单示例
2016/10/08 PHP
AJAX的使用方法详解
2017/04/29 PHP
laravel 5.4 + vue + vux + element的环境搭配过程介绍
2018/04/26 PHP
js 固定悬浮效果实现思路代码
2013/08/02 Javascript
js setTimeout opener的用法示例详解
2013/10/23 Javascript
jquery无法设置checkbox选中即没有变成选中状态
2014/03/27 Javascript
JS实现带圆弧背景渐变效果的导航菜单代码
2015/10/13 Javascript
Javascript中的迭代、归并方法详解
2016/06/14 Javascript
jQuery Easyui使用(一)之可折叠面板的布局手风琴菜单
2016/08/17 Javascript
JS实现前端缓存的方法
2017/09/21 Javascript
Vue组件化开发思考
2018/02/02 Javascript
javascript实现自由编辑图片代码详解
2019/06/21 Javascript
浅析微信小程序modal弹窗关闭默认会执行cancel问题
2019/10/14 Javascript
Vue-Cli项目优化操作的实现
2019/10/27 Javascript
python协程之动态添加任务的方法
2019/02/19 Python
python+os根据文件名自动生成文本
2019/03/21 Python
Python 实现Serial 与STM32J进行串口通讯
2019/12/18 Python
浅谈Python 命令行参数argparse写入图片路径操作
2020/07/12 Python
解决python运行效率不高的问题
2020/07/20 Python
PyQt实现计数器的方法示例
2021/01/18 Python
计算机应用毕业生自荐信
2013/10/23 职场文书
金属材料工程个人求职的自我评价
2013/12/04 职场文书
公司庆典邀请函范文
2014/01/13 职场文书
事业单位考核材料
2014/05/21 职场文书
广告学专业求职信
2014/06/19 职场文书
公务员爱岗敬业演讲稿
2014/08/26 职场文书
公司离职证明范本
2014/10/17 职场文书
质监局领导班子践行群众路线整改方案
2014/10/26 职场文书
2014年学校总务处工作总结
2014/12/08 职场文书
大学运动会通讯稿
2015/07/18 职场文书
《火烧云》教学反思
2016/02/23 职场文书
SQL SERVER中常用日期函数的具体使用
2021/04/08 SQL Server
防止web项目中的SQL注入
2021/12/06 MySQL
Apache SeaTunnel实现 非CDC数据抽取
2022/05/20 Servers