如何在create-react-app项目中使用vw实现手淘vw移动端适配布局

7,076 阅读4分钟

2018年是我感觉是前端的插件年,在css方面,postcss的插件也是刚刚的,无论是autoprefixer,还是postcss-cssnext等一系列方面,今天刚好做一个移动端新项目,特意请教了手淘团队,出了一个新方案,开始抛弃使用Flexible实现手淘H5页面的终端适配,使用vw布局方案,关于vue-cli使用的配置已经有讲解,我就讲讲create-react-app的配置

具体的内容原因请下以面链接

w3cplus vm布局

配置方面就不用说了,如何用creat-react-app生成一个项目,运行起来,请看以下链接

https://reactjs.org/docs/forms.html

直接进入如何配置

生成项目后,直接进行 webpack.config.dev.js,配置开发环境配置找到这段代码

              {
                loader: require.resolve('postcss-loader'),
                options: {
                  config: {
                    path: 'postcss.config.js'  // 这个得在项目根目录创建此文件
                  },
                  // Necessary for external CSS imports to work
                  // https://github.com/facebookincubator/create-react-app/issues/2677
                  ident: 'postcss'
                  // plugins: () => [
                  //   require('postcss-flexbugs-fixes'),
                  //   autoprefixer({
                  //     browsers: [
                  //       '>1%',
                  //       'last 4 versions',
                  //       'Firefox ESR',
                  //       'not ie < 9', // React doesn't support IE8 anyway
                  //     ],
                  //     flexbox: 'no-2009',
                  //   }),
                  // ],
                },
              },

create-react-app 自己配置了,内联的autoprefixer,把它注示掉,然后在options里加指向的配置地址,把所有的plugins插件配置全放入一个在项目根目标的postcss.config.js,通过postcss解析的时候自然会运行这些差件,因为运用大量的配置,在生产环境同样要同到,进行一个共同配置。

在配置之前先下一些包

npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano cssnano-preset-advanced --D

postcss.config.js配置


module.exports = {
    "plugins": [
        require('postcss-flexbugs-fixes'),
        require("autoprefixer")({
            browsers: [
                '>1%',
                'last 4 versions',
                'Firefox ESR',
                'not ie < 9', // React doesn't support IE8 anyway
            ],
            flexbox: 'no-2009',
        }),
        require("postcss-aspect-ratio-mini"),
        require("postcss-write-svg")({ utf8: false }),
        require("postcss-cssnext"),
        require("postcss-px-to-viewport")({
            viewportWidth: 750,
            viewportHeight: 1334,
            unitPrecision: 3,
            viewportUnit: 'vw',
            selectorBlackList: ['.ignore', '.hairlines'],
            minPixelValue: 1,
            mediaQuery: false
        }),
        require("postcss-viewport-units"),
        require("cssnano")({
            preset: "advanced",
            autoprefixer: false,
            "postcss-zindex": false
        })

    ]
}

以上的配置原理还是请到 w3cplus vm布局

require('postcss-flexbugs-fixes'),
        require("autoprefixer")({
            browsers: [
                '>1%',
                'last 4 versions',
                'Firefox ESR',
                'not ie < 9', // React doesn't support IE8 anyway
            ],
            flexbox: 'no-2009',
        }),

为了不破坏整体性还是把create-react-app原本的差件搬过来。关于postcss的配置就结束了

改一下public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta name="theme-color" content="#000000">
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <script src="//g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></script>
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
    <script>
      window.onload = function () {
        window.viewportUnitsBuggyfill.init({
          hacks: window.viewportUnitsBuggyfillHacks
        });

        var winDPI = window.devicePixelRatio;
            var uAgent = window.navigator.userAgent;
            var screenHeight = window.screen.height;
            var screenWidth = window.screen.width;
            var winWidth = window.innerWidth;
            var winHeight = window.innerHeight;
            alert(
                "Windows DPI:" + winDPI +
                ";\ruAgent:" + uAgent +
                ";\rScreen Width:" + screenWidth +
                ";\rScreen Height:" + screenHeight +
                ";\rWindow Width:" + winWidth +
                ";\rWindow Height:" + winHeight
            )
      }
    </script>
  </body>
</html>

引入 viewport-units-buggyfill.hacks的ali cdn 再初始化执行init方法

ok此时配置完成,运行 npm start

注意几点: viewportWidth: 750 可以当作是iphone6的视口度,你的设计图也要是750的比例,也是移动端的标准设计比。正常的用px,最后会/2进行一个比例换算。

解决安桌机0.5px线的问题,需要通过postcss-write-svg,对于我这种不懂svg的,是一个很奇秒的设计, 示例请看原作者。

当你写好之后,发现chrome 控制台是换成了vw,就是成功了,如果设置了最小转化值minPixelValue: 1,说明小于等于1px的不进行vw的转换。

在生产环境webpack.production.config.js中,与dev也是同样的配置。

感谢手淘团队,感w3cPlus 大漠