1. 条件编译:多平台导航栏差异处理
场景:在微信小程序中自定义导航栏,而H5端使用默认导航栏样式。
案例:
<!-- 仅微信小程序隐藏默认导航栏,H5保留 -->
<!-- #ifdef MP-WEIXIN -->
<view class="custom-navbar">
<text>自定义导航栏</text>
</view>
<!-- #endif -->
<style>
/* #ifdef MP-WEIXIN */
.custom-navbar {
height: 60px; /* 微信自定义导航栏高度 */
background: #FF0000;
}
/* #endif */
/* #ifdef H5 */
/* H5使用原生导航栏,无需额外样式 */
/* #endif */
</style>
优势:
- 精准控制:仅在小程序端插入自定义导航栏代码,避免H5端冗余DOM。
- 避免冲突:防止不同平台的导航栏样式互相覆盖。
2. CSS媒体查询:PC与移动端布局切换
场景:同一页面在PC端显示三列,移动端显示一列。
案例:
/* 默认移动端样式 */
.product-list {
padding: 20rpx;
}
.product-item {
width: 100%;
margin-bottom: 20rpx;
}
/* PC端适配(屏幕宽度≥992px) */
@media (min-width: 992px) {
.product-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.product-item {
width: 32%; /* 三列布局 */
margin-bottom: 0;
}
}
优势:
- 无代码侵入:纯CSS实现布局切换,无需修改逻辑层。
- 横竖屏适配:自动响应屏幕方向变化(如平板旋转)。
3. Flex布局:动态等高瀑布流
场景:实现左右两列等高且内容自适应的瀑布流布局。
案例:
<view class="container">
<view class="left-column">
<!-- 左侧内容(高度不确定) -->
</view>
<view class="right-column">
<!-- 右侧内容(高度不确定) -->
</view>
</view>
<style>
.container {
display: flex;
justify-content: space-between;
}
.left-column, .right-column {
width: 48%; /* 留出间距 */
display: flex;
flex-direction: column; /* 子元素垂直排列 */
}
/* 关键:通过flex-grow拉伸容器高度 */
.left-column > view, .right-column > view {
flex-grow: 1;
margin-bottom: 20rpx;
}
</style>
优势:
- 等高自适应:左右两列内容高度不同时,容器始终保持等高。
- 内容流式布局:新增内容自动向下排列,无需手动计算高度。
4. rpx单位:复杂屏幕等比缩放
场景:设计稿为750px宽度,需在iPhone 12(390px宽度)和iPad(1024px宽度)上等比缩放。
案例:
/* 设计稿中一个按钮宽度为200px */
.confirm-btn {
width: 200rpx; /* 转换为200rpx */
}
/* 在iPhone 12上计算为:200 * (390/750) = 104px */
/* 在iPad上计算为:200 * (1024/750) ≈ 273px */
优势:
- 设计稿1:1还原:开发直接按设计稿数值编写,无需手动计算百分比。
- 自动跨端适配:不同屏幕尺寸自动缩放,避免H5中rem计算的兼容性问题。
5. 动态样式绑定:主题切换与暗黑模式
场景:用户点击切换主题(浅色/深色),并实时更新全局样式。
案例:
<template>
<view :style="themeStyle">
<!-- 页面内容 -->
</view>
<button @click="toggleTheme">切换主题</button>
</template>
<script>
export default {
data() {
return {
isDarkMode: false
};
},
computed: {
themeStyle() {
return {
'--bg-color': this.isDarkMode ? '#000000' : '#FFFFFF',
'--text-color': this.isDarkMode ? '#FFFFFF' : '#333333'
};
}
},
methods: {
toggleTheme() {
this.isDarkMode = !this.isDarkMode;
}
}
};
</script>
<style>
/* 使用CSS变量 */
page {
background-color: var(--bg-color);
color: var(--text-color);
transition: all 0.3s; /* 平滑过渡 */
}
</style>
优势:
- 实时响应:通过Vue计算属性动态更新CSS变量,无需刷新页面。
- 全局控制:一键切换所有关联样式,避免逐元素修改。
6. 组件封装:统一多端弹窗样式
场景:封装一个弹窗组件,自动处理iOS/Android的关闭按钮位置差异。
案例:
<!-- components/custom-modal.vue -->
<template>
<view class="modal-mask">
<view class="modal-content">
<slot name="header"></slot>
<slot name="body"></slot>
<!-- 条件编译关闭按钮位置 -->
<!-- #ifdef APP-PLUS -->
<view class="close-btn ios-style" @click="close">X</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="close-btn android-style" @click="close">关闭</view>
<!-- #endif -->
</view>
</view>
</template>
<style>
.modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
}
.modal-content {
width: 80%;
margin: 100rpx auto;
background: white;
padding: 30rpx;
}
/* iOS风格关闭按钮 */
.ios-style {
position: absolute;
top: 10rpx;
right: 10rpx;
}
/* Android风格关闭按钮 */
.android-style {
text-align: center;
padding: 20rpx;
border-top: 1px solid #eee;
}
</style>
优势:
- 开箱即用:业务层直接引入
<custom-modal>
,无需关心平台差异。 - 样式隔离:组件内聚平台特定代码,避免污染全局样式。
终极方案:组合使用模式
场景:商品详情页需适配手机/平板/PC,且支持主题切换。
<template>
<view
class="product-detail"
:style="themeStyle"
:class="{'pc-layout': isPC}"
>
<!-- 条件编译:小程序端显示返回首页按钮 -->
<!-- #ifdef MP-WEIXIN -->
<view class="home-button" @click="goHome">首页</view>
<!-- #endif -->
<!-- 主体内容(Flex布局) -->
<view class="content-wrapper">
<image class="product-image" :src="imageUrl"></image>
<view class="product-info">
<text class="title">{{ productName }}</text>
<text class="price">{{ price }}元</text>
</view>
</view>
</view>
</template>
<script>
export default {
computed: {
isPC() {
const { screenWidth } = uni.getSystemInfoSync();
return screenWidth >= 768; // 平板及以上尺寸
},
themeStyle() {
// 从Vuex获取主题
return this.$store.state.theme;
}
}
};
</script>
<style>
.product-detail {
padding: 20rpx;
}
.content-wrapper {
display: flex;
flex-direction: column; /* 默认垂直排列 */
}
.pc-layout .content-wrapper {
flex-direction: row; /* PC端横向排列 */
}
.product-image {
width: 100%;
height: 300rpx;
}
.pc-layout .product-image {
width: 50%;
height: 500rpx;
}
.home-button {
position: fixed;
top: 20rpx;
left: 20rpx;
padding: 10rpx 20rpx;
background: #007AFF;
color: white;
}
</style>
组合优势:
- 条件编译:针对性处理平台专属元素(如小程序按钮)。
- 动态样式:根据主题和屏幕尺寸自动切换布局。
- Flex布局:无缝适应不同排列方式。
- rpx单位:图片尺寸自动响应屏幕变化。
总结:如何选择适配模式
问题类型 | 推荐方案 | 示例 |
---|---|---|
平台特定样式 | 条件编译 + 组件封装 | 微信小程序自定义导航栏 |
响应式布局 | Flex + 媒体查询 | PC/平板/手机三端适配 |
动态主题/样式 | Vue动态样式绑定 + CSS变量 | 用户切换暗黑模式 |
快速开发标准UI | UI框架(uView/Vant) | 表单、按钮、弹窗组件 |
设计稿精准还原 | rpx单位 + Flex布局 | 实现与设计稿像素级匹配的列表 |
通过以上案例,可以更清晰地看到不同适配模式的实际应用场景和解决问题的思路。建议在项目中根据具体需求混合使用多种模式,而非局限于单一方案。