Vue 關於移動端的那些事情(一)

想法

最近公司項目可能會用到vue的技術,趁如今有時間,就開始搞移動端的適配,爲了方便開發,個人想法是(viewport+rem+flex)。rem那塊須要進行一個換算須要作一個適配處理,爲了方便最好是根據規定的圖(本文采用iPhone6)編寫px,而後經過工具對px進行轉換成rem(px2rem)。好了,需求已經理清了,開搞!!!。css

行動

關於適配問題的解決方案

第一種適配方案

在網上查看資料,找到一個挺好的解決方案,若是你是用vue-cli的話你可能要注意一下,在index.html頁面須要將 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 刪除。html

詳情看代碼 前端

檢查適配viewprot

代碼以下vue

!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("將根據已有的meta標籤來設置縮放比例");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;j=1/(i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1)}if(f.setAttribute("data-dpr",i),!g)if((g=e.createElement("meta")).setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",(function(){clearTimeout(d),d=setTimeout(c,300)}),!1),a.addEventListener("pageshow",(function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))}),!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",(function(){e.body.style.fontSize=12*i+"px"}),!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
複製代碼

適配成功的效果node

適配成功的效果

對應機型

第二種適配方案

lib-flexible是手機淘寶出的一套解決方案,原理差很少。android

  1. npm i -S amfe-flexible

github地址:裏面有實例能夠看,不過好像要錢,我就拉倒了,沒錢並且個人方案不是vw去適配方案,不必去看!git

不過要注意一點就是不能刪除index.html<meta name="viewport" content="width=device-width, initial-scale=1.0">github

緣由是代碼中是沒有對viewport進行適配的,它只是根據規則去換算htmlfont-size正則表達式

  1. 在項目入口文件main.js中引入lib-flexible

import 'lib-flexible/flexible.js'vue-cli

  1. 花裏胡哨,看我
html{ font-size: 10vw; }
複製代碼

感謝QAQ青桔的提出!@_@!


關於rem的轉換方案

我採用的是postcss-plugin-px2rem這個插件

npm install postcss-plugin-px2rem --save-dev

配置步驟

  1. 打開vue-loader.conf.js若是的項目是新鮮沒改過請參考一下,主要配置在postcss這個方法裏面
<!--導入postcss-plugin-px2rem-->
const px2rem = require('postcss-plugin-px2rem');
<!--導出配置-->
module.exports = {
  loaders: utils.cssLoaders({
    sourceMap: sourceMapEnabled,
    extract: isProduction
  }),
  cssSourceMap: sourceMapEnabled,
  cacheBusting: config.dev.cacheBusting,
  transformToRequire: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: 'xlink:href'
  },
  <!--px2rem的主要配置-->
  postcss: function () {
    return [
      px2rem(
        {
          rootValue: 75, //換算基數, 默認100 
          unitPrecision: 8, //容許REM單位增加到的十進制數字。
          // propWhiteList: ["font-size"],  //默認值是一個空數組,這意味着禁用白名單並啓用全部屬性。
          propBlackList: ["font-size"], //黑名單
          exclude: /(node_module)/,  //默認false,能夠(reg)利用正則表達式排除某些文件夾的方法,例如/(node_module)/ 。若是想把前端UI框架內的px也轉換成rem,請把此屬性設爲默認值
          // selectorBlackList: [], //要忽略並保留爲px的選擇器
          // ignoreIdentifier: false,  //(boolean/string)忽略單個屬性的方法,啓用ignoreidentifier後,replace將自動設置爲true。
          // replace: true, // (布爾值)替換包含REM的規則,而不是添加回退。
          mediaQuery: false,  //(布爾值)容許在媒體查詢中轉換px。
          minPixelValue: 3 //設置要替換的最小像素值(3px會被轉rem)。 默認 0
        }
      )
    ];
  }
}

複製代碼

或者是找到.postcssrc.js文件

<!--參考配置-->
module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {},
    "postcss-plugin-px2rem": {
      rootValue: 37.5, //換算基數, 默認100 
      unitPrecision: 3, //容許REM單位增加到的十進制數字。
      // propWhiteList: ["font-size"],  //默認值是一個空數組,這意味着禁用白名單並啓用全部屬性。
      // propBlackList: [], //黑名單
      exclude: /(node_module)/,  //默認false,能夠(reg)利用正則表達式排除某些文件夾的方法,例如/(node_module)/ 。若是想把前端UI框架內的px也轉換成rem,請把此屬性設爲默認值
      // selectorBlackList: [], //要忽略並保留爲px的選擇器
      // ignoreIdentifier: false,  //(boolean/string)忽略單個屬性的方法,啓用ignoreidentifier後,replace將自動設置爲true。
      // replace: true, // (布爾值)替換包含REM的規則,而不是添加回退。
      mediaQuery: false,  //(布爾值)容許在媒體查詢中轉換px。
      minPixelValue: 3 //設置要替換的最小像素值(3px會被轉rem)。 默認 0
    },
  }
}
複製代碼

以上配置二選一便可

若是你不須要這麼複雜的配置也能夠考慮一下 px2rem-loader

npm install px2rem-loader --save-devutils.js文件中配置對應的地方配置

var px2remLoader = {
    loader: 'px2rem-loader',
    options: {
        remUnit: 75 // 75px = 1rem
        remPrecision: 8 // rem的小數點後位數
    }
  }
    // generate loader string to be used with extract text plugin
  function generateLoaders(loader, loaderOptions) {
    const loaders = options.usePostCSS ? [cssLoader, postcssLoader,px2remLoader] : [cssLoader,px2remLoader]
    if (loader) {
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, {
          sourceMap: options.sourceMap
        })
      })
    }

    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader'
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
  }
  
複製代碼

基本看看效果先

less

less
效果
效果

最後

謝謝你們!但願能對大家有所幫助,有什麼問題能夠在評論下方提出,期待有更好的解決方案,學習一下!咱們下篇再見!


請勿未經容許轉載,謝謝合做

聯繫我:652165177(QQ)

相關文章
相關標籤/搜索