移动端适配方案

5,637 阅读2分钟

移动端主流适配方案

主要考虑通过 rem 来适配

方案一.监听窗口变化动态设置根字体大小

在 main.js 或者 vue 根组件 created 阶段,手动给 window 添加事件监听设置根字体大小

export function setRootSize() {
  document.documentElement.style.fontSize =
    (100 * window.innerWidth) / 375 + "px";
  window.addEventListener("load", function () {
    setTimeout(() => {
      document.documentElement.style.fontSize =
        (100 * window.innerWidth) / 375 + "px";
      window.unit = (100 * window.innerWidth) / 375;
      let e = document.createEvent("Event");
      e.initEvent("adjustReady", true, true);
      window.dispatchEvent(e);
    }, 480);
  });
  window.onresize = () => {
    setTimeout(() => {
      document.documentElement.style.fontSize =
        (100 * window.innerWidth) / 375 + "px";
    }, 480);
  };
  window.addEventListener("orientationchange", () => {
    setTimeout(() => {
      document.documentElement.style.fontSize =
        (100 * window.innerWidth) / 375 + "px";
    }, 480);
  });
}

这么设置,比如 phonex 屏幕 375。那么 32px 的大小就很方便地口算成.32rem

方案 2.手淘的 amfe-flexible 插件配合 postcss-px2rem

npm 安装对应的插件安装包

// main.js
import "amfe-flexible";
// webpack css相关loader中
exports.cssLoaders = function (options) {
  options = options || {}

  const px2remLoader = {
    loader: 'px2rem-loader',
    options: {
      remUnit: 37.5,
      // remUnit: 100,
    }
  }

  const cssLoader = {
    loader: 'css-loader',
    options: {
      sourceMap: options.sourceMap
    }
  }

  const postcssLoader = {
    loader: 'postcss-loader',
    options: {
      sourceMap: options.sourceMap
    }
  }

  // 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)
    }
  }

  // https://vue-loader.vuejs.org/en/configurations/extract-css.html
  return {
    css: generateLoaders(),
    postcss: generateLoaders(),
    less: generateLoaders('less'),
    sass: generateLoaders('sass', { indentedSyntax: true }),
    scss: generateLoaders('sass'),
    stylus: generateLoaders('stylus'),
    styl: generateLoaders('stylus')
  }
}

postcss-px2rem这个插件,作用就是把你写的px转化成rem,没有适配屏幕变化的作用,不会改变根字体大小,如果是只配置这个插件:

  1. rem大小不会变化,1rem还是默认的16px像素
  2. px会按这个配置的大小转化,即配37.5,那么100px=>100/37.5=2.6666rem;
  3. PX大写不会转化,100PX就还是100PX; 所以这样是有些不一致的,你写1rem是16px,你写37.5px又是1rem,并且vant组件的大小显示也不对了(必须配成100才能正确显示)。

使用这个插件之后,可以配合使用rootSize或者amfe-flexible来设置根字体大小,但配置大小有所不同:

  1. remUnit:100,rootSize也100px,原来50px写成.5rem,现在直接写50px了,省去了自己换算的过程。
  2. remUnit:37.5,配合直接使用amfe-flexible,配置之后也是直接按px大小写。