在移动端,通常都会使用 REM + FLEX 布局 来实现移动端的完美适配。

rem 就是根元素(html)的 font-size 属性。

Flex布局请参考:Flex 布局教程

当然,如果你使用的 UI 库是 Cube-UI 的话,那么这个库里面自带了适配方案,可以不使用下面的这种方案,如果使用别的 UI 库的话,就可以使用这种方案。

我们可以使用 amfe-flexible 依赖来实现 REM 的书写,然后通过 px2rem-loader 依赖来帮我们把 px 自动转换成 rem,这样我们就可以在书写的时候直接写 px 单位,可以不用我们进行 rem 的单位换算。

amfe-flexible:可以根据设备的宽度,自动的修改根元素(html)的大小,以达到适配不同终端的作用。

px2rem-loader:可以将 CSS 中的 px 单位 转换为 rem 单位,可以自动的计算 rem 的值,书写的时候更加方便。

安装


npm  install -s amfe-flexible

npm install px2rem-loader --save -dev

配置


在入口文件 main.js 中引入:

import 'amfe-flexible';

index.html 中 修改 meta 属性:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

vue.config.js 中或者自己的工具类中配置 px2rem-loader(这里我是在 vue.config.js 中配置的):

:在 vue-cli3.x 中默认是没有 vue.config.js 配置文件的,需要手动进行创建,位置在项目根目录

const px2remLoader = {
    loader: 'px2rem-loader',
    options: {
        remUnit: 75 // 默认换算为 1rem = 75px,可根据你的设计稿修改(设计稿/10),如果设计稿宽度是 1080,则此处应该填写 108
    }
}
// 在 generateLoaders 方法中添加 px2remLoader
function generateLoaders(loader, loaderOptions) {
    const loaders = options.usePostCSS ? [cssLoader, postcssLoader, px2remLoader] : [cssLoader, px2remLoader]
    if (loader) {
        loaders.push({
            loader: loader + '-loader',
            options: Object.assign({}, loaderOptions, {
                sourceMap: options.sourceMap
            })
        })
    }
    if (options.extract) {
        return ExtractTextPlugin.extract({
            use: loaders,
            fallback: 'vue-style-loader'
        })
    } else {
        return ['vue-style-loader'].concat(loaders)
    }
}

使用


配置好以后,就可以直接使用了。

默认会在我们的根节点(html)中添加一个 font-size 属性,可以根据设备进行自适应数值大小。

效果展示:

2024/08/22/1724303901406.webp

手动加入 JS 适配


<script>
	;(function () {
		// 设计稿宽度 px
		var designWidth = 375
		// rem 基准字号 px
		var baseFontSize = 100
		// 最大适配宽度 px
		var maxAdaptWidth = 1024

		var adaptDevice = function () {
			var deviceWidth = document.documentElement.clientWidth
			deviceWidth = deviceWidth > maxAdaptWidth ? maxAdaptWidth : deviceWidth
			var scale = deviceWidth / designWidth
			var adaptRootFontSize = baseFontSize * scale
			document.querySelector('html').style.fontSize = adaptRootFontSize + 'px'
		}

		var timer = 0
		window.addEventListener('resize', function () {
			if (timer) {
				clearTimeout(timer)
				timer = 0
			}

			timer = setTimeout(function () {
				adaptDevice()
			}, 0)
		})

		setTimeout(adaptDevice, 0)
	}())
</script>