详解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创建一个欢迎cookie弹出窗实现代码
Mar 15 Javascript
JS 退出系统并跳转到登录界面的实现代码
Jun 29 Javascript
tangram框架响应式加载图片方法
Nov 21 Javascript
jQuery文件上传控件 Uploadify 详解
Jun 20 Javascript
任意Json转成无序列表的方法示例
Dec 09 Javascript
bootstrap modal弹出框的垂直居中
Dec 14 Javascript
原生js实现淘宝购物车功能
Jun 23 Javascript
BootStrap 表单控件之单选按钮水平排列
May 23 Javascript
详解基于vue-router的动态权限控制实现方案
Sep 28 Javascript
vue自定义指令directive实例详解
Jan 17 Javascript
JS跨域请求的问题解析
Dec 03 Javascript
webpack 如何同时输出压缩和未压缩的文件的实现步骤
Jun 05 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编程最快明白》第八讲:php启发和小结
2010/11/01 PHP
PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
2012/04/09 PHP
ThinkPHP框架搭建及常见问题(XAMPP安装失败、Apache/MySQL启动失败)
2016/04/15 PHP
Thinkphp3.2实用篇之计算型验证码示例
2017/02/09 PHP
JS提交并解析后台返回的XML的代码
2008/11/03 Javascript
javascript中的遍历for in 以及with的用法
2014/12/22 Javascript
javascript实现全角半角检测的方法
2015/07/23 Javascript
jquery实现移动端点击图片查看大图特效
2020/09/11 Javascript
jQuery mobile类库使用时加载导航历史的方法简介
2015/12/04 Javascript
jQuery实现鼠标经过时高亮,同时其他同级元素变暗的效果
2016/09/18 Javascript
js遍历json对象所有key及根据动态key获取值的方法(必看)
2017/03/09 Javascript
Express + Session 实现登录验证功能
2017/09/08 Javascript
纯js封装的ajax功能函数与用法示例
2018/05/14 Javascript
JavaScript闭包原理与用法实例分析
2018/08/10 Javascript
NodeJs 模仿SIP话机注册的方法
2019/06/21 NodeJs
python使用urllib2实现发送带cookie的请求
2015/04/28 Python
Python正则抓取新闻标题和链接的方法示例
2017/04/24 Python
Python学习之用pygal画世界地图实例
2017/12/07 Python
对Python 数组的切片操作详解
2018/07/02 Python
python占位符输入方式实例
2019/05/27 Python
关于python导入模块import与常见的模块详解
2019/08/28 Python
python图形用户接口实例详解
2019/12/16 Python
Macbook安装Python最新版本、GUI开发环境、图像处理、视频处理环境详解
2020/02/17 Python
python3 使用ssh隧道连接mysql的操作
2020/12/05 Python
Roots加拿大官网:加拿大休闲服饰品牌
2016/10/24 全球购物
Joie官方网上商店:购买服装和女装配饰
2018/06/05 全球购物
伦敦香水公司:The London Perfume Company
2019/11/13 全球购物
大学生入党思想汇报
2014/01/01 职场文书
生产部主管岗位职责
2014/01/06 职场文书
建筑工程技术专业求职信
2014/07/16 职场文书
群众路线教育查摆剖析材料
2014/10/10 职场文书
班主任先进事迹材料
2014/12/17 职场文书
教师个人师德工作总结2015
2015/05/12 职场文书
2016新教师培训心得体会范文
2016/01/08 职场文书
《围炉夜话》110句人生箴言,精辟有内涵,引人深思
2019/10/23 职场文书
Django debug为True时,css加载失败的解决方案
2021/04/24 Python