详解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 相关文章推荐
jQuery源码分析-01总体架构分析
Nov 14 Javascript
JS实现单行文字不间断向上滚动的方法
Jan 29 Javascript
JavaScript实现数组在指定位置插入若干元素的方法
Apr 06 Javascript
jQuery实现响应鼠标滚动的动感菜单效果
Sep 21 Javascript
jQuery EasyUI Pagination实现分页的常用方法
May 21 Javascript
jQuery遍历DOM的父级元素、子级元素和同级元素的方法总结
Jul 07 Javascript
BootStrap入门教程(二)之固定的内置样式
Sep 19 Javascript
js判断用户是输入的地址请求的路径(实例讲解)
Jul 18 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
Nov 28 Javascript
微信小程序实现下拉刷新动画
Jun 21 Javascript
原生js实现商品筛选功能
Oct 28 Javascript
javascript前端实现多视频上传
Dec 13 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
dedecms系统常用术语汇总
2007/04/03 PHP
JavaScript实现禁止后退的方法
2006/12/27 Javascript
自动生成文章摘要的代码[JavaScript 版本]
2007/03/20 Javascript
编辑浪子版表单验证类
2007/05/12 Javascript
js call方法详细介绍(js 的继承)
2013/11/18 Javascript
深入理解JavaScript中的箭头函数
2015/07/28 Javascript
AngularJS整合Springmvc、Spring、Mybatis搭建开发环境
2016/02/25 Javascript
json格式的javascript对象用法分析
2016/07/04 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
2016/12/18 Javascript
bootstrap按钮插件(Button)使用方法解析
2017/01/13 Javascript
JS触摸与手势事件详解
2017/05/09 Javascript
详解Vue.use自定义自己的全局组件
2017/06/14 Javascript
详解写好JS条件语句的5条守则
2019/02/28 Javascript
laypage.js分页插件使用方法详解
2019/07/27 Javascript
Layui 带多选框表格监听事件以及按钮自动点击写法实例
2019/09/02 Javascript
微信JSSDK实现打开摄像头拍照再将相片保存到服务器
2019/11/15 Javascript
python中类的一些方法分析
2014/09/25 Python
用Q-learning算法实现自动走迷宫机器人的方法示例
2019/06/03 Python
python同时替换多个字符串方法示例
2019/09/17 Python
python获得命令行输入的参数的两种方式
2020/11/02 Python
HTML5去掉输入框type为number时的上下箭头的实现方法
2020/01/03 HTML / CSS
科沃斯机器人官网商城:Ecovacs
2016/08/29 全球购物
天美时手表加拿大官网:Timex加拿大
2016/09/01 全球购物
世界上最大的乐器零售商:Guitar Center
2017/11/07 全球购物
英国独特礼物想法和个性化礼物网站:notonthehighstreet.com
2018/04/16 全球购物
英国领先的名牌服装折扣零售商:Brown Bag Clothing
2019/01/08 全球购物
小学教师的个人自我鉴定
2013/10/26 职场文书
职业教育毕业生求职信
2013/11/09 职场文书
卫生安全检查制度
2014/02/04 职场文书
开门红主持词
2014/04/02 职场文书
中考标语大全
2014/06/05 职场文书
IT工程师岗位职责
2014/07/04 职场文书
公司授权委托书范文
2014/08/02 职场文书
离职告别感言
2015/08/04 职场文书
交通安全宣传标语(100条)
2019/08/22 职场文书
Win11 22H2 2022怎么更新? 获得Win1122H22022版本升级技巧
2022/09/23 数码科技