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

postcss-url

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

autoprefixer

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

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

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中,cssnanocss-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引入它们:
   <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>

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

(2)调用viewport-units-buggyfill:
<script>
    window.onload = function () {
        window.viewportUnitsBuggyfill.init({
            hacks: window.viewportUnitsBuggyfillHacks
        });
    }
</script>
(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 <img> 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342