文章目录
- 前言
- 一、使用插件
- ① 纯wap项目
- 效果:
- Demo:
- ② pc&wap混合项目(我放弃了)
- 二、老方案
- 效果:
- Demo:
前言
最近在给公司内部做一个BBS论坛,需要在电脑和手机上都可以操作,所以需要做移动端的适配,下面是我在开发后觉得不错的一些解决方案,分享给大家。
一、使用插件
在vue2的时候我们可以使用lib-flexible + postcss-pxtorem 去对移动端进行适配,不过lib-flexible
这个过度方案弃用了,所以我们可以在vue3中用amfe-flexible + postcss-pxtorem,vant也推荐用这两搭配,老实说,vant是真的香(づ ̄3 ̄)づ。
vant 推荐使用在=》进阶用法=》Rem 布局适配 :传送门
下面来看一下这两插件怎么用吧,我们先执行命令安装这两插件(测试用的vue版本是3.2.13)
amfe-flexible:目前执行默认指向2.2.1版本
npm i -S amfe-flexible
postcss-pxtorem 目前执行默认指向6.0.0版本
npm install postcss-pxtorem --save-dev
安装完后我们先在main.js
中引入amfe-flexible
import 'amfe-flexible'
接着在项目根目录新建一个postcss.config.js
文件
Vue3脚手架项目
|-public
|-src
|-postcss.config.js
① 纯wap项目
如果你的项目不考虑放PC端的页面的话,直接把下面的代码拷贝到上面创建的js文件里就好了:
// postcss.config.js
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue({ file }) {
return file.indexOf('vant') !== -1 ? 37.5 : 75; // 因为vant框架是以375px的稿子为基础的,所以需要适配一下
},
propList: ['*'], // 需要转换的css属性,默认*全部
}
}
}
配置完之后我们就可以在项目中以px为单位去开发了,是的,不用我们手动敲rem转换去开发了,PS设计稿的宽度以750px
为基准,否则需要自己调一下,开发时稿子是1px,你就写1px就好了,插件会帮我们换算成rem。
效果:
我用vant4
简单搭了个项目,从GIF中可以看到px都自动转化成rem了,vue的logo我给了375px
的宽高,当窗口宽度为750
像素时,logo的实际宽高是375px
,也就是说我们只要按750的设计稿去写,就能以1:1进行页面还原了。
Demo:
如果你的项目完全不用考虑pc端的话,可以参考参考这个demo。
下载地址:vue3-page-adapter-m
② pc&wap混合项目(我放弃了)
如果你的项目既要放手机端的页面,又要放电脑端的页面,那么我是不推荐你用amfe-flexible + postcss-pxtorem去适配你的项目的,至于为什么,可以看看下面我踩的坑。
本地工作目录:
Vue3脚手架项目
|-src
|-views
|-m
|-pc
比如说你的工作目录有两个文件夹,一个用来放手机端的页面,一个用来放电脑端的页面,那么我们肯定是不想pc文件夹里的页面被转换成rem,也不想pc端的ui框架(element plus)被转换成rem,那么postcss-pxtorem提供了下面4中形式来处理是否需要把pc转化成rem:
rootValue({ file })
:转换比率propList[]
: 需要转换的css属性,默认*全部,比如不想字体被转换,那就在数组里面加入'!font-size'
selectorBlackList[]
:不需要转换的class类名exclude
:不需要转换的文件夹,可以使用三种形式:字符串(String
)、正则表达式(Regexp
)、 函数(Function
)
首先为了不让pc文件夹下面的页面自动转化成rem,我配置了exclude
参数来区分,之后pc文件夹下的vue文件的样式确实不会自动转换了,但是引入element plus
后,拖动窗口你会发现el组件自动缩放了,是的,就算你在配置好的pc文件夹里使用去第三方框架,第三方框架还是会自动转化成rem,于是我配置了selectorBlackList
,于是我把有关el
和:root
的类名全部设置成不自动转换,之后el组件确实不会自动缩放了,但是这样的话手机端的vant组件不会自动缩放了,除非手动去设置像素大小,这是因为第三方框架的一些基础属性都是放在:root
下,具体看下面的GIF:
至于为什么要设置
:root
类名,因为el组件的默认值都在这个类名下,不排除的话一些字体会转化成rem,导致字体自动缩放;另外你可能还会问el组件的默认值都是--el
开头的属性,为什么不用propList去排除?我试过,不行)
相关代码:
// postcss.config.js
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue({ file }) {
return file.indexOf('vant') !== -1 ? 37.5 : 75; // 因为vant框架是以375px的稿子为基础的,所以需要适配一下
},
propList: ['*'], // 需要转换的css属性,默认*全部
selectorBlackList: ['el',':root'], // 不需要转换的class类名
exclude: 'src\\views\\pc' // 不需要转换的文件夹
// exclude: /src\\views\\pc/i
// exclude: function (file) { return file.indexOf('src\\views\\pc') !== -1; }
}
}
}
接着我又尝试在rootValue里有关element-plus组件的都返回false,结果vant框架能缩放了,element框架能不自动缩放了,但是:root
类名里的--el
的一些默认值都被替换成了Infinityrem
,所以el的一些字体、高度、圆角等默认值都不会有了,(╯°Д°)╯︵┻━┻,我选择狗带了。
相关代码:
// postcss.config.js
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue({ file }) {
if (file.indexOf('element-plus') !== -1) return false
return file.indexOf('vant') !== -1 ? 37.5 : 75; // 因为vant框架是以375px的稿子为基础的,所以需要适配一下
},
propList: ['*'], // 需要转换的css属性,默认*全部
selectorBlackList: ['el'], // 不需要转换的class类名
exclude: 'src\\views\\pc' // 不需要转换的文件夹
// exclude: /src\\views\\pc/i
// exclude: function (file) { return file.indexOf('src\\views\\pc') !== -1; }
}
}
}
经过一顿操作后,还是没有办法很好的用amfe-flexible
+ postcss-pxtorem
去兼顾pc+wap的项目,并且考虑后续pc端不可能只用element框架,所以我放弃这种方案了
二、老方案
最后,为了项目里能同时兼顾pc端和wap端,我还是选择用了以前写原生时的方案,不清楚的可以看看我之前写的文章:传送门,下面来看一下可行性吧。
Vue3脚手架项目
|-public
|-index.html
我们先在index.html
文件的<head>
标签里加入下面的代码:
<script>
const isMobile = () => {
const flag = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)
return flag ? true : false;
}
if (isMobile()) {
//封装响应式像素方法,初始化单位,实现手机端1rem=100px
const responsivePX = () => {
//获取页面的宽度
let deviceWidth = document.documentElement.clientWidth;
//如果页面大于750,即px端的页面,则把html的像素锁死在100px
if (deviceWidth > 750) deviceWidth = 750;
document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px';
}
// 第一次初始化像素大小
responsivePX();
// 监听窗口二次刷新像素大小
window.onresize = () => {
responsivePX();
};
}
</script>
这段代码的大致功能是监听到设备是移动端时,就会根据窗口的大小去动态设置html的字体大小,之后我们就可以在项目中以rem为单位去开发移动端了,为了防止字体过大,我做了限制,就是当屏幕大于750时,最大字体仍旧是100px,当屏幕刚好等于750时,rem和px的比例为1:100
,也就是说用750像素的设计稿去开发,比如页面宽度是100px,那么我们代码里写1rem就行了,相信都能看懂,不多说了。
效果:
用老方案的话完全不用担心pc端会自动缩放了,因为在pc环境我们压根就没动态设置html根标签的字体,唯一比较麻烦的是写移动端页面时要换算成rem,还有就是因为不会自动把px转化成rem,所以第三方框架并不会自动缩放,比如vant的组件,它是有默认的px值的,如果你想要某个组件自动缩放的话,手动设置一下rem就好,其实一些组件不设置缩放我反而会觉得看得更舒服,比如tabbar,这个因人而异吧,问题不大。需要注意的是如果你用了vant的tabbar,会有一部分视野挡住内容,需要根据你设置的高度或默认的高度去设置下padding,具体可以看下GIF:
Demo:
如果你的项目需要把pc端和wap端放一块写,可以参考参考这个demo。
下载地址:vue3-page-adapter-pc-m