阅读 2771

Vue 关于移动端的那些事情(一)

想法

最近公司项目可能会用到vue的技术,趁现在有时间,就开始搞移动端的适配,为了方便开发,我的想法是(viewport+rem+flex)。rem那块需要进行一个换算需要做一个适配处理,为了方便最好是根据规定的图(本文采用iPhone6)编写px,然后通过工具对px进行转换成rem(px2rem)。好了,需求已经理清了,开搞!!!。

行动

关于适配问题的解决方案

第一种适配方案

在网上查看资料,找到一个挺好的解决方案,如果你是用vue-cli的话你可能要注意一下,在index.html页面需要将 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 删除。

详情看代码

检查适配viewprot

代码如下

!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={}));
复制代码

适配成功的效果

适配成功的效果

对应机型

第二种适配方案

lib-flexible是手机淘宝出的一套解决方案,原理差不多。

  1. npm i -S amfe-flexible

github地址:里面有实例可以看,不过好像要钱,我就拉倒了,没钱而且我的方案不是vw去适配方案,没必要去看!

不过要注意一点就是不能删除index.html<meta name="viewport" content="width=device-width, initial-scale=1.0">

原因是代码中是没有对viewport进行适配的,它只是根据规则去换算htmlfont-size

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

import 'lib-flexible/flexible.js'

  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)

关注下面的标签,发现更多相似文章
评论