参考文章
5 分钟过下移动端适配方案 - 掘金
一篇文章搞懂,vue中pc端与移动端适配解决方案(亲测有效) - 掘金
移动端适配
媒体查询方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @media screen and (max-width:375px) { .box { width: 100%; } }
@media screen and (min-width:375px) and (max-width:450px) { .box { width: 90%; } }
@media screen and (min-width:450px) { .col{ width: 80%; } }
|
缺点
- 页面上所有的元素都得在不同的 @media 中定义一遍不同的尺寸,代价有点高。
- 如果再多一种屏幕尺寸,就得多写一个 @media 查询块。
rem方案
- 安装插件
1 2
| npm install amfe-flexible --save npm install postcss-pxtorem --save-dev
|
- 在
main.js
中引入amfe-flexible
, 该插件会根据不同设备的屏幕宽度来设置html
的font-size
值
- 在
postcss.config.js
文件中配置postcss-pxtorem
postcss-pxtorem
是一个能将px
转换为rem
的工具
1 2 3 4 5 6 7 8 9 10 11
| module.exports = { "plugins": { "postcss-pxtorem": { rootValue({ file }) { return file.indexOf('vant') !== -1 ? 37.5 : 75; }, propList: ['*'] } } }
|
也可以在 vite.config.js
中配置 postcss-pxtorem
1 2 3 4 5 6 7 8 9 10 11
| css:{ postcss:{ plugins:[ postCssPxToRem({ rootValue:37.5, propList:['*'], }) ] } }
|
public/index.html
添加viewport
元数据标签,使页面宽度和设备宽度一致
1 2 3 4 5 6 7 8 9 10
| <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
执行上述步骤之后,就可以使用px
进行开发了, px
单位会被自动转换成rem
单位。
viewport方案
public/index.html
添加viewport
元数据标签,使页面宽度和设备宽度一致
1
| <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
- 安装插件
1
| npm install postcss-px-to-viewport --save-dev
|
- 在
postcss.config.js
文件中配置postcss-px-to-viewport
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| module.exports = ({ file }) => { const vwUnit = file && file.indexOf('vant') !== -1 ? 375 : 750; return { plugins: { 'postcss-px-to-viewport': { viewportWidth: vwUnit, unitPrecision: 5, viewportUnit: 'vw', propList: ['*'], selectorBlackList: [], minPixelValue: 1, mediaQuery: true, }, }, }; };
|
执行上述步骤之后,就可以使用px
进行开发了,px
单位会被自动转换成vw
单位。
补充
amfe-flexable
是阿里发布的一套可伸缩适配方案。
它能根据设备的宽高来设置页面body
元素的字体大小,将1rem
设置为设备宽度/10
以及在页面大小转换时可以重新计算这些数值。
postcss-pxtorem
是postcss的一个插件,可以将对应的像素单位转换为rem
。
在vite
中可以直接对其进行配置,因为vite
已经集成了postcss
。
其中最重要的配置属性为:
- rootValue:根元素的值,即1rem对应的像素值大小。一般设置为
设计稿尺寸/10
以及一些其他属性:
- propList:需要进行转换的css属性的值,可以使用通配符。如:
*
意思是将全部属性单位都进行转换;
1
| ["*position*"]`会匹配到`background-position-y
|
- selectorBlackList:不进行单位转换的选择器。如设置为字符串
body
,则所有含有body字符串的选择器都不会被该插件进行转换;若设置为[/^body$/]
,则body
会被匹配到而不是.body
- exclude:不需要进行单位转换的文件
- mediaQuery:是否允许像素在媒体查询中进行转换
PC端适配
rem方案
- 安装依赖
1 2
| pnpm add amfe-flexible pnpm add postcss-pxtorem
|
- 在main.js中引入amfe-flexible
amfe-flexible 等价代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
function setRem() { const screenWidth = 1920 const scale = screenWidth / 16 const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth const htmlDom = document.getElementsByTagName('html')[0] htmlDom.style.fontSize = htmlWidth / scale + 'px' } setRem() window.onresize = function() { setRem() }
|
- 配置vue.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
module.exports=function(){ devServer:{ port:3000, open:true }, css: { loaderOptions: { postcss: { plugins: [ require('postcss-pxtorem')({ rootValue: 149, propList: ['*'], }) ] } } }, }
|
存在问题
不能使用行内样式
对于行内样式,阿里手淘并不能将px转rem,所以对于需要自适应的样式,如font-size、width、height等请不要写在行内。同理,对于不需要转化的样式可以写在行内,或者使用PX(大写)作为单位。
暂未找到可以转行内rem的插件。
viewport方案
- 安装
1
| pnpm add postcss-px-to-viewport -D
|
- 与
src
同目录 新建postcss.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| export const plugins = { 'postcss-px-to-viewport': { unitToConvert: 'px', viewportWidth: 1494, unitPrecision: 5, propList: ['*'], viewportUnit: 'vw', fontViewportUnit: 'vw', selectorBlackList: [], minPixelValue: 1, mediaQuery: false, replace: true, exclude: undefined, include: undefined, landscape: false, landscapeUnit: 'vw', landscapeWidth: 1494 } }
|
可以看看这篇文章 ~~ 比较全
移动端适配及PC端适配心得总结体会(一) (可能比较全 - 掘金