vue3微信公众号商城项目实战系列(5)页面适配手机屏幕
上一篇完成了2个页面之间的跳转,在浏览器中也可以正常浏览和跳转,但这2个页面并没有为适配手机屏幕设计,
如果我们用 chrome 浏览器模拟手机屏幕的大小后再看,结果如下图:
(注:用 chrome 模拟手机屏幕只需要在正常情况下按下 F12 键,然后点击 红框2 处的小图标就可以了
,改变模拟屏幕的大小可在 红框1 处修改数字,也可以鼠标按住边框的双线拖动大小,尺寸的单位是像素)
模拟的手机屏幕尺寸是 375像素 x 628像素,看上去是正常的。
但如果我们浏览之前的 HelloWorld.vue页面,内容就被遮住了,如下图:
(注:我们考虑屏幕大小的时候只需关注宽度,因为手机屏幕高度是可以自动带滚动条往下滑动来浏览页面的,这符合用户的使用习惯,
如果横向带滚动条,这样的设计就非常奇怪,而且从手机本身的物理尺寸上来看,高度远大于宽度,纵向的可视范围更大,
所以手机端应用在设计页面的时候一般只考虑屏幕宽度就可以了)
自然地 , 我们会想到在<template>中编写页面的时候就限制页面宽度统一为375像素是否可行呢?大部分情况是可以的
,因为现在的手机像素已经很高了,宽度一般都在375像素以上,完全够显示375像素宽的页面而没有遮挡
,但可能带来另外一个问题,就是当手机屏幕宽度大于500像素,甚至1000像素的时候,页面内容会变得非常小。
为了演示这种情况 , 我们先把全局样式 main.css 修改一下,把页面预设的 padding和margin全部置0,确保 .vue 页面能完全占满屏幕不留空隙
,body元素也加上1px的红色边框以便有更好的对比效果。如下图:
然后再给 Welcome.vue 定义一个固定宽度 375px,如下:
<template> <div class="welcome"> <span>欢迎回来</span> <router-link to="/home">浏览进入</router-link> </div> </template> <style> .welcome{ width: 375px; margin: 0 auto; border: solid 1px blue; } </style>
在浏览器中刷新页面,结果如下:
看上去一切都好 。 然后把模拟屏幕的宽度调到500px,高度等比例放大到837px ,刷新页面后效果如下:
可以看到页面宽度已经不能占满屏幕了,右侧出现了空白,如果把宽度再调大一点,空白区域会更大。
而现在用户的手机屏幕宽度绝大部分是超过375px,如果一个商城网站按 375px 排版
,那不同的手机尺寸展示出来的商品页面布局会五花八门,这不但给用户体验不好,而且浪费了寸土寸金的屏幕空间
, 有没有可能让375px排版好的页面在不同手机屏幕自动缩放从而填满整个屏幕宽度呢 ?
答案是:有的。
目前有两种解决方案:
方案1. 使用 postcss-px2rem 这个js包 ,它能将 px 自动转化成 rem 单位 ,而 rem 是相对根元素字体大小的单位,从而达到自动缩放的效果。
方案2. 使用 postcss-px-to-viewport 包,它是将 px 自动转化成 vw 单位 , 1vw=1%屏幕宽度,即不管屏幕实际有多少个像素,1vw就占用
屏幕宽度的 1% ,100vw自然就占满屏幕了。
-----------------------------------------------------------------------------------------------------------------------------
本系列采用方案2 。
这样我们就很好的解决了布局的问题,设计稿只要定义一个基准宽度,比如 375px(定义成535px 、750px等任意值都可以)
,所有页面元素在设置px大小的时候只要保证这些元素宽度之和=375px(即设计稿定义的宽度) , 那页面就可以在任意尺寸的手机上
呈现和设计稿上一样的效果,不再有留白或遮挡,一切都在掌握中。
注:为了尽可能在不同分辨率的手机上浏览时保证图片的清晰度和字体大小适中,我们定义设计稿的宽度为 375px 。使用 postcss-px-to-viewport 非常简单:
第1步 ,安装包,指令:npm install postcss-px-to-viewport
第2步,在vite.config.js中配置参数,如下:
添加引用
import postcsspxtoviewport from 'postcss-px-to-viewport'
添加配置
css: {
postcss: {
plugins: [
postcsspxtoviewport({
unitToConvert: 'px', // 要转化的单位
viewportWidth: 375, // UI设计稿的宽度
unitPrecision: 6, // 转换后的精度,即小数点位数
propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: ['ignore-'], // 指定不转换为视窗单位的类名,
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否转换后直接更换属性值
exclude: [],// 设置忽略文件,用正则做目录名匹配
landscape: false // 是否处理横屏情况
})
]
}
}
刷新页面,效果如下:
可以看到,虽然调大了屏幕宽度(图1),页面仍然占满了屏幕(图2),元素的单位也自动变成了 vw且精确到了小数后6位(图3),实现了想要的效果。
注:图3的宽度是 98.666667, 是因为笔者把 Welcome.vue 中元素宽度改成了 370px 的缘故(如下),实际项目中建议稍稍留一点安全间隙,防止有些机型布局错乱。
<style> .welcome{ width: 370px; margin: 0 auto; border: solid 1px blue; } </style>