Vue2.x 中使用vw完成移动端页面适配

如果你还对使用vw做移动端页面适配不了解,这里推荐大漠老师的两篇文章

再聊移动端页面的适配和如何在Vue项目中使用vw实现移动端适配

随着视口单位被众多浏览器所支持,我们现在完全可以使用vw来做移动端的适配问题。下面就介绍一下Vue2.x 中使用vw实现移动端页面适配的步骤。代码


前提

你已经了解vue cli来构建项目。无论使用vue cli 2.x 还是3.x 版本,如果你了解webpack配置,那么过程都是大同小异。首先我们初始化一个项目:

vue init webpack vue-mb-vw

进入项目:

cd vue-mb-vw

启动项目:

npm run dev

1. 安装一些PostCSS插件

在项目的根目录下有一个.postcssrc.js,默认情况下已经安装了以下几个插件:

  • postcss-import
  • postcss-url
  • autoprefixer
postcss-import

postcss-import主要功有是解决@import引入路径问题。使用这个插件,可以让你很轻易的使用本地文件、node_modules文件

postcss-url

该插件主要用来处理文件,比如图片文件、字体文件等引用路径的处理。在Vue项目中, vue-loader 已具有类似的功能

autoprefixer

autoprefixer插件是用来自动处理浏览器前缀的一个插件

为了完成vw的布局兼容方案并简化我们的工作,还需要安装配置下面的几个PostCSS插件:

  • postcss-px-to-viewport
  • postcss-cssnext
  • cssnano
  • postcss-aspect-ratio-mini
  • postcss-write-svg
  • postcss-viewport-units
npm i  postcss-px-to-viewport postcss-cssnext cssnano   postcss-aspect-ratio-mini  postcss-write-svg  postcss-viewport-units --save-dev

接下来在.postcssrc.js文件对新安装的PostCSS插件进行配置:

module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // "autoprefixer": {},
    "postcss-aspect-ratio-mini": {}, 
    "postcss-write-svg": {
        utf8: false
    },
    "postcss-cssnext": {},
    "postcss-px-to-viewport": {
            viewportWidth: 750,     // (Number) The width of the viewport.
            unitPrecision: 3,       // (Number) The decimal numbers to allow the REM units to grow to.
            viewportUnit: 'vw',     // (String) Expected units.
            propList:['*','!font','!font-size'],
            selectorBlackList: ['.ignore', '.hairlines'],  // (Array) The selectors to ignore and leave as px.
            minPixelValue: 1,       // (Number) Set the minimum pixel value to replace.
            mediaQuery: false       // (Boolean) Allow px to be converted in media queries.
    }, 
    "postcss-viewport-units":{},
     "cssnano": {
            preset: "advanced",
            autoprefixer: false,
            "postcss-zindex": false
        }
  }
}

注意:由于cssnext和cssnano都具有autoprefixer。所以需要把默认的autoprefixer删除掉,然后把cssnano中的autoprefixer设置为false,我们使用cssnext的autoprefixer。

将viewportWidth设为我们视觉稿的尺寸,这里使用750px的视觉稿

postcss-px-to-viewport

postcss-px-to-viewport插件主要用来把px单位转换为vwvhvmin或者vmax这样的视窗单位,也是vw适配方案的核心插件之一。配置我们参考官网

postcss-cssnext

postcss-cssnext其实就是cssnext。该插件可以让我们使用CSS未来的特性,其会对这些特性做相关的兼容性处理。

cssnano

cssnano主要用来压缩和清理CSS代码。在Webpack中,cssnano和 css-loader捆绑在一起,所以不需要自己加载它。不过你也可以使postcss-loader显式的使用cssnano

cssnano的配置中,使用了preset: "advanced",所以我们需要另外安装cssnano-preset-advanced:

npm i cssnano-preset-advanced --save-dev

cssnano集成了一些其他的PostCSS插件,如果你想禁用cssnano中的某个插件的时候,可以像下面这样操作:

"cssnano": {
    autoprefixer: false,
    "postcss-zindex": false
}

上面的代码把autoprefixerpostcss-zindex禁掉了。前者是有重复调用,后者只要启用了,z-index的值就会重置为1,我们需要禁用。

postcss-aspect-ratio-mini

postcss-aspect-ratio-mini主要用来处理元素容器宽高比。在实际使用的时候,具有一个默认的结构,用法可以去github查看。

postcss-write-svg

postcss-write-svg插件主要用来处理移动端1px的解决方案。该插件主要使用的是border-imagebackground来做1px的相关处理。

postcss-viewport-units

postcss-viewport-units插件主要是给CSS的属性添加content的属性,配合viewport-units-buggyfill库给vwvhvminvmax做适配的操作。

这是实现vw布局必不可少的一个插件,因为少了这个插件,这将是一件痛苦的事情。


2. 兼容vw

让浏览器兼容视口单位的最终的解决方案就是使用viewport-units-buggyfill

viewport-units-buggyfill主要有两个JavaScript文件:viewport-units-buggyfill.js和viewport-units-buggyfill.hacks.js。

(1)在vue项目中的index.html引入它们:
   

当然你也可以使用其他CDN,或者使用npm安装

(2)调用viewport-units-buggyfill:

(3)在使用了视口单位地方,添加content

在你的CSS中,只要使用到了viewport的单位(vwvhvminvmax )地方,需要在样式中添加content

ul {
   display: flex;
   flex-wrap: wrap;
   justify-content: space-between;
   font-size: 18px;
   list-style-type: none;
   padding:20px;
    /* hack to engage viewport-units-buggyfill */
    content: "viewport-units-buggyfill; padding: 2.667vw";
}

如果每次都需要手动书写,会极大地增加我们的工作量。这个时候就需要前面提到的postcss-viewport-units 插件。这个插件将让你无需关注content的内容,插件会自动帮你处理。

viewport-units-buggyfill还提供了其他的功能,详细的这里不阐述了。


3.常见问题

(1)遇到不想px转换为vw的地方,可以添加指定的类名像.ignore。然后在 "postcss-px-to-viewport"插件配置中的selectorBlackList属性添加这个类名即可
(2)使用了ui框架的,需要避免px转vw。可以在 "postcss-px-to-viewport"插件配置中的exclude属性添加ui框架的目录,将其排除在外
(3)Viewport Units Buggyfill添加的content也会引起一定的副作用。比如

The content hack may not work well on and other replaced elements, even though it should compute to content: normal; on regular elements. If you find yourself in such a situation, this may be a way out:

img {
  content: normal !important;
}

This buggyfill only works on stylesheets! viewport units used in style attributes are not resolved.

The buggyfill can easily trip over files host on different origins (requiring CORS) and relative URLs to images/fonts/… within stylesheets. #11

你可能感兴趣的:(Vue2.x 中使用vw完成移动端页面适配)