场景:
next.js v14
适配方案:
viewport
前置:
设置meta标签 禁止缩放等
在根目录的layout.tsx里配置Meta标签;
import type { Viewport } from 'next';
...
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
maximumScale: 1,
minimumScale: 1,
userScalable: false,
};
这样就行了,next.js会自动渲染成meta标签。
当然你也可以手动写meta标签放到head里;
我这里适配方案有两种:
- css in js
使用css in js的话不需要引入什么插件了,由于1vw = 当前屏幕宽度的1%,我们稍微封装下直接使用就ok了 - less/scss预处理
借助postcss 我们可以用px2vw 自动将像素转成viewport;
css in js方案
我是用的是styled-components
这个库
- 先安装
pnpm add styled-components
- 配置next.config.js
配置config.js文件让其支持style component
const nextConfig = {
...
compiler: {
styledComponents: true,
},
...
}
- 封装一个方法处理px2vw
config.viewportWidth
属性是适配设计稿的宽度 比如设计稿是375 这里就是375
config.unitPrecision
属性是转换后的精度(小数点多少位)
import config from '@/static/config';
export const vw = (n: number) => {
return `${+((n / config.viewportWidth) * 100).toFixed(config.unitPrecision)}vw`;
};
- 使用
直接引入styled和刚封装的vw方法
import styled from 'styled-components';
import { vw } from '@/utils';
...
const List = styled.div`
width: ${vw(100)};
...
`;
css预处理方法
由于next.js内置了postcss,所以我们不需要再安装postcss/postcss-loader
我这里借助的转换依赖是postcss-px-to-viewport-8-plugin
- 安装依赖
pnpm add -D postcss-px-to-viewport-8-plugin
- 配置postcss.config.js文件(没有就自己创建这个文件,位于根目录)
配置参数,我这里由于需要做h5到pc自适应,所以我H5的css使用的是rpx单位,经过postcss-px-to-viewport-8-plugin
插件的转化,会转换成vw单位;
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
'postcss-px-to-viewport-8-plugin': {
unitToConvert: 'rpx',
viewportWidth: 375,
unitPrecision: 10,
propList: ['*'],
viewportUnit: 'vw',
fontViewportUnit: 'vw',
selectorBlackList: [],
minPixelValue: 0,
mediaQuery: false,
replace: true,
exclude: [],
landscape: false,
landscapeUnit: 'vw',
landscapeWidth: 568,
},
},
};
tips: tailwindcss/autoprefixer是我安装的依赖,没安装的可以删除这两项,否则会报错!!!
- 在scss/less/css文件里直接使用配置的
unitToConvert
单位即可自动将其转换成vw单位;
以上就是我适配移动端的方案;
注意事项:
postcss-px-to-viewport-8-plugin
是无法处理内联样式的,就是说你写在标签style里的属性是不会被转换的,要注意!如果非要用的话可以考虑使用vw
方法转换。