详解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获取网页属性包括宽、高等等
Apr 03 Javascript
js数组与字符串的相互转换方法
Jul 09 Javascript
jQuery实现友好的轮播图片特效
Jan 12 Javascript
node.js操作mongodb学习小结
Apr 25 Javascript
javascript实现在网页中运行本地程序的方法
Feb 03 Javascript
微信小程序 购物车简单实例
Oct 24 Javascript
JS重载实现方法分析
Dec 16 Javascript
JS实现复制内容到剪贴板功能
Feb 05 Javascript
angular十大常见问题
Mar 07 Javascript
js实现本地时间同步功能
Aug 26 Javascript
vue绑定的点击事件阻止冒泡的实例
Feb 08 Javascript
jquery 键盘事件 keypress() keydown() keyup()用法总结
Oct 23 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
使用 MySQL 开始 PHP 会话
2006/12/21 PHP
php set_magic_quotes_runtime() 函数过时解决方法
2010/07/08 PHP
php实现过滤UBB代码的类
2015/03/12 PHP
thinkPHP数据查询常用方法总结【select,find,getField,query】
2017/03/15 PHP
PHP编程快速实现数组去重的方法详解
2017/07/22 PHP
ThinkPHP防止重复提交表单的方法实例分析
2018/05/10 PHP
IE中createElement需要注意的一个问题
2010/07/13 Javascript
jquery showModelDialog的使用方法示例详解
2013/11/19 Javascript
JQuery Tips相关(1)----关于$.Ready()
2014/08/14 Javascript
javascript动态设置样式style实例分析
2015/05/13 Javascript
js实现跨域的几种方法汇总(图片ping、JSONP和CORS)
2015/10/25 Javascript
轻松学习jQuery插件EasyUI EasyUI创建树形菜单
2015/11/30 Javascript
JavaScript中for循环的几种写法与效率总结
2017/02/03 Javascript
EasyUI的DataGrid绑定Json数据源的示例代码
2017/12/16 Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
2018/01/25 Javascript
详解Node使用Puppeteer完成一次复杂的爬虫
2018/04/18 Javascript
Vue 使用 Mint UI 实现左滑删除效果CellSwipe
2018/04/27 Javascript
浅谈Vue响应式(数组变异方法)
2018/05/07 Javascript
vue组件挂载到全局方法的示例代码
2018/08/02 Javascript
JS实现继承的几种常用方式示例
2019/06/22 Javascript
vue框架制作购物车小球动画效果实例代码
2019/09/26 Javascript
vue跳转方式(打开新页面)及传参操作示例
2020/01/26 Javascript
python翻译软件实现代码(使用google api完成)
2013/11/26 Python
python如何压缩新文件到已有ZIP文件
2018/03/14 Python
Python查找第n个子串的技巧分享
2018/06/27 Python
django的csrf实现过程详解
2019/07/26 Python
python怎么自定义捕获错误
2020/06/29 Python
python利用线程实现多任务
2020/09/18 Python
美国球迷装备的第一来源:FOCO
2020/07/03 全球购物
Java如何调用外部Exe程序
2015/07/04 面试题
cf战队收人广告词
2014/03/14 职场文书
党性锻炼的心得体会
2014/09/03 职场文书
2014年最新大专生职业生涯规划书范文
2014/09/13 职场文书
2015年办公室人员工作总结
2015/05/15 职场文书
公司员工违法违章行为检讨书
2019/06/24 职场文书
MySQL查看表和清空表的常用命令总结
2021/05/26 MySQL