前言

1.为了使项目适配于各种pc端分辨率,所以使用了此插件
2.设计图尺寸是1920
3.根据大多数移动端使用情况,只适配了微信系统
4.vue2-cli5

"vue": "^2.6.14",
node--16.14.2          
vue2+cli5---ant design vue

1.安装postcss-pxtorem

npm install postcss-pxtorem --save-dev

2.安装lib-flexible

npm i lib-flexible -D

2.1main.js

import 'lib-flexible/flexible'

3.配置

3.1 若vue.config.js配置起作用可以不用建后面3.2的postcss.config.js

我使用的框架配置无效,所以使用了3.2中的方法

npm install postcss-plugin-px2rem -S
css: {
  loaderOptions: {
    sass: {
      sassOptions:{
        outputStyle:'expanded'
      },
      // @/ 是 src/ 的别名
      // 因此这里假设你有 `src/variables.sass` 这个文件
      // 注意:在 sass-loader v7 中,这个选项名是 "data"
      prependData: `@import "~@/variables.sass"`
    },
    scss: {
      //   prependData: `@import "~@/variables.scss";`
    },
    postcss: {
      postcssOptions: {
        plugins: [
          require('postcss-plugin-px2rem')({
            rootValue: 192,      // 新版本的是这个值
            mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
            minPixelValue: 3 //设置要替换的最小像素值(3px会被转rem)。 默认 0
          }),
        ]
      },
    }
  },
},

3.2因是vue2+vue-cli5所以配置使用的是vue3+vue-cli3的配置根目录新建postcss.config.js

module.exports = {
  "plugins": {
    "postcss-pxtorem": {
      "rootValue": 192,//设计图是1920
      "propList": ["*"],
      minPixelValue: 12, // px小于12的不会被转换
      unitPrecision: 2, // 保留rem小数点多少位
      selectorBlackList: ['ig'] // 忽略的选择器
    },
    'autoprefixer': {browsers: ['Android >= 5.0', 'iOS >= 8']},
  }
}

3.3为了平台稳定,插件使用了离线

在plugins下面新建flexible.js文件,然后在main.js中引入import ‘@/plugins/flexible.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(){
    let { width } = docEl.getBoundingClientRect();
    if (width / dpr > 540) {
      width *= dpr;
    }
    //此处进行了修改,注释部分为原码
    const rem = width / 10;
    docEl.style.fontSize = `${rem}px`;
    flexible.rem = win.rem = rem;
    // 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'] = {}));

4.适配移动端微信系统

在plugins下新建fontSize.js

(function(doc, win) {
  let u = navigator.userAgent;
  let isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1; //android终端
  let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
  if(isAndroid){
    //      用原生方法获取用户设置的浏览器的字体大小(兼容ie)
    if(doc.documentElement.currentStyle) {
      var user_webset_font=doc.documentElement.currentStyle['fontSize'];
    }
    else {
      var user_webset_font=getComputedStyle(doc.documentElement,false)['fontSize'];
    }
//      取整后与默认16px的比例系数
    var xs=parseFloat(user_webset_font)/16;
//      设置rem的js设置的字体大小
    var view_jsset_font,result_font;
    var docEl = doc.documentElement,
      resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
      clientWidth,
      recalc = function() {
        clientWidth = docEl.clientWidth;
        if(!clientWidth) return;
        if(!doc.addEventListener) return;
        if(clientWidth<750){
//              设置rem的js设置的字体大小
          view_jsset_font=270 * (clientWidth / 750);
//              最终的字体大小为rem字体/系数
          result_font=view_jsset_font/xs;
//              设置根字体大小
          docEl.style.fontSize = result_font + 'px';
        }
      };
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener('DOMContentLoaded', recalc, false);
  } else if(isIOS){
//      用原生方法获取用户设置的浏览器的字体大小(兼容ie)
    if(doc.documentElement.currentStyle) {
      var user_webset_font=doc.documentElement.currentStyle['fontSize'];
    }
    else {
      var user_webset_font=getComputedStyle(doc.documentElement,false)['fontSize'];
    }
//      取整后与默认16px的比例系数
    var xs=parseFloat(user_webset_font)/16;
//      设置rem的js设置的字体大小
    var view_jsset_font,result_font;
    var docEl = doc.documentElement,
      resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
      clientWidth,
      recalc = function() {
        clientWidth = docEl.clientWidth;
        if(!clientWidth) return;
        if(!doc.addEventListener) return;
        if(clientWidth<750){
//              设置rem的js设置的字体大小
          view_jsset_font=230 * (clientWidth / 750);
//              最终的字体大小为rem字体/系数
          result_font=view_jsset_font/xs;
//              设置根字体大小
          docEl.style.fontSize = result_font + 'px';
        }
      };
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener('DOMContentLoaded', recalc, false);
  }
})(document, window);

本想通过js修改手机里面的默认字体大小,或者使手机默认字体不影响body的font-size,试了好几种方法不管用,最后使用了上面js解决

Logo

前往低代码交流专区

更多推荐