11 KiB
11 KiB
消费者端多端适配方案
一、项目现状分析
1.1 当前技术栈
- 框架: uni-app x (Vue 3 + UTS)
- 已支持平台:
- Android App (已验证)
- 微信小程序 (已验证)
- H5 (配置已就绪)
- 其他小程序平台 (支付宝、百度、头条等配置已就绪)
1.2 项目结构
pages/mall/consumer/ # 消费者端页面
├── doc/ # 文档目录
├── index.uvue # 首页
├── category.uvue # 分类页
├── product-detail.uvue # 商品详情
├── cart.uvue # 购物车
├── checkout.uvue # 结算页
├── orders.uvue # 订单列表
├── profile.uvue # 个人中心
└── ...
二、多端适配方案对比
方案一:单项目多端编译(推荐)
核心思路: 一套代码,通过条件编译和平台判断,编译到不同平台。
优点:
- 代码复用率高,维护成本低
- 统一的技术栈和开发流程
- Bug修复一次,全平台生效
- 符合 uni-app x 的设计理念
缺点:
- 需要处理各平台差异
- 部分平台特性需要条件编译
- 小程序包体积限制需要注意
实现方式:
// 条件编译示例
// #ifdef MP-WEIXIN
// 微信小程序特有代码
// #endif
// #ifdef APP-ANDROID
// Android App 特有代码
// #endif
// #ifdef H5
// H5 特有代码
// #endif
方案二:多项目独立开发
核心思路: 为每个平台创建独立项目,共享核心业务逻辑。
优点:
- 各端可独立优化
- 不受其他平台限制
- 可针对平台特性深度定制
缺点:
- 维护成本高,代码重复
- Bug需要多端修复
- 开发周期长
适用场景:
- 各端差异极大
- 需要深度定制平台特性
- 有充足的开发资源
方案三:核心库 + 平台适配层
核心思路: 抽离核心业务逻辑为共享库,各平台实现适配层。
优点:
- 核心逻辑统一
- 平台适配灵活
- 便于团队协作
缺点:
- 架构复杂度高
- 需要良好的抽象设计
- 初期开发成本较高
三、推荐方案:单项目多端编译
基于项目现状,推荐采用方案一,原因如下:
- uni-app x 天然支持多端编译
- 当前代码已具备良好的跨端基础
- 维护成本最低,开发效率最高
四、具体实施步骤
4.1 平台配置
4.1.1 微信小程序配置
// manifest.json
{
"mp-weixin": {
"appid": "你的微信小程序AppID",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true
},
"usingComponents": true,
"optimization": {
"subPackages": true
}
}
}
4.1.2 支付宝小程序配置
// manifest.json
{
"mp-alipay": {
"appid": "你的支付宝小程序AppID",
"usingComponents": true
}
}
4.1.3 H5 配置
// manifest.json
{
"h5": {
"title": "商城消费者端",
"router": {
"mode": "history",
"base": "/consumer/"
},
"devServer": {
"port": 8080,
"proxy": {
"/api": {
"target": "https://your-api.com",
"changeOrigin": true
}
}
}
}
}
4.2 条件编译处理
4.2.1 平台判断工具类
// utils/platform.uts
// 平台类型
export type PlatformType = 'android' | 'ios' | 'weixin' | 'alipay' | 'h5' | 'unknown'
// 获取当前平台
export function getCurrentPlatform(): PlatformType {
// #ifdef APP-ANDROID
return 'android'
// #endif
// #ifdef APP-IOS
return 'ios'
// #endif
// #ifdef MP-WEIXIN
return 'weixin'
// #endif
// #ifdef MP-ALIPAY
return 'alipay'
// #endif
// #ifdef H5
return 'h5'
// #endif
return 'unknown'
}
// 判断是否为小程序环境
export function isMiniProgram(): boolean {
const platform = getCurrentPlatform()
return platform === 'weixin' || platform === 'alipay'
}
// 判断是否为 App 环境
export function isApp(): boolean {
const platform = getCurrentPlatform()
return platform === 'android' || platform === 'ios'
}
4.2.2 API 适配层
// utils/apiAdapter.uts
import { getCurrentPlatform, isMiniProgram, isApp } from './platform.uts'
// 支付适配
export function requestPayment(orderId: string, amount: number): Promise<any> {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
// 微信小程序支付
uni.requestPayment({
provider: 'wxpay',
timeStamp: '',
nonceStr: '',
package: '',
signType: 'MD5',
paySign: '',
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef MP-ALIPAY
// 支付宝小程序支付
my.tradePay({
tradeNO: orderId,
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef APP-ANDROID || APP-IOS
// App 支付
uni.requestPayment({
provider: 'wxpay', // 或 'alipay'
orderInfo: orderId,
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef H5
// H5 支付(跳转到支付页面)
window.location.href = `/payment?orderId=${orderId}`
resolve({})
// #endif
})
}
// 登录适配
export function platformLogin(): Promise<any> {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
// 微信小程序登录
uni.login({
provider: 'weixin',
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef MP-ALIPAY
// 支付宝小程序登录
my.getAuthCode({
scopes: 'auth_user',
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef APP-ANDROID || APP-IOS
// App 登录(使用账号密码或第三方登录)
// 跳转到登录页面
uni.navigateTo({ url: '/pages/user/login' })
resolve({})
// #endif
})
}
// 分享适配
export function shareProduct(productId: string, title: string, imageUrl: string): void {
// #ifdef MP-WEIXIN
// 微信小程序分享(通过 onShareAppMessage)
// 在页面中定义 onShareAppMessage 即可
// #endif
// #ifdef MP-ALIPAY
// 支付宝小程序分享
// #endif
// #ifdef APP-ANDROID || APP-IOS
// App 分享
uni.share({
provider: 'weixin',
scene: 'WXSceneSession',
type: 0,
title: title,
imageUrl: imageUrl,
success: () => console.log('分享成功'),
fail: (err) => console.error('分享失败', err)
})
// #endif
}
4.3 样式适配
4.3.1 响应式样式
/* 基础样式 */
.container {
padding: 20rpx;
}
/* 小程序适配 */
/* #ifdef MP-WEIXIN || MP-ALIPAY */
.container {
padding: 30rpx; /* 小程序通常需要更大的间距 */
}
/* #endif */
/* H5 适配 */
/* #ifdef H5 */
.container {
max-width: 750rpx;
margin: 0 auto;
}
/* #endif */
/* 电脑端适配 */
@media screen and (min-width: 1025px) {
.container {
max-width: 1200px;
padding: 40rpx;
}
}
4.3.2 安全区域适配
/* 底部安全区域 */
.safe-area-bottom {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
/* 顶部安全区域 */
.safe-area-top {
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
}
4.4 功能差异处理
4.4.1 小程序特有功能
// 小程序特有功能封装
export function initMiniProgramFeatures(): void {
// #ifdef MP-WEIXIN
// 微信小程序更新检查
const updateManager = uni.getUpdateManager()
updateManager.onUpdateReady(() => {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: (res) => {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
// #endif
}
4.4.2 App 特有功能
// App 特有功能封装
export function initAppFeatures(): void {
// #ifdef APP-ANDROID || APP-IOS
// 检查 App 更新
checkAppUpdate()
// 推送通知初始化
initPushNotification()
// #endif
}
五、小程序分包策略
5.1 分包配置
// pages.json
{
"pages": [
{
"path": "pages/main/index",
"style": { "navigationBarTitleText": "首页" }
},
{
"path": "pages/main/category",
"style": { "navigationBarTitleText": "分类" }
},
{
"path": "pages/main/cart",
"style": { "navigationBarTitleText": "购物车" }
},
{
"path": "pages/user/center",
"style": { "navigationBarTitleText": "我的" }
}
],
"subPackages": [
{
"root": "pages/mall/consumer",
"pages": [
{
"path": "product-detail",
"style": { "navigationBarTitleText": "商品详情" }
},
{
"path": "checkout",
"style": { "navigationBarTitleText": "结算" }
},
{
"path": "orders",
"style": { "navigationBarTitleText": "订单" }
},
{
"path": "payment",
"style": { "navigationBarTitleText": "支付" }
}
]
}
],
"preloadRule": {
"pages/main/index": {
"network": "all",
"packages": ["pages/mall/consumer"]
}
}
}
5.2 分包原则
- 主包: 仅包含首页、分类、购物车、个人中心等核心页面
- 分包: 包含商品详情、订单、支付等次级页面
- 预加载: 在首页预加载分包,提升用户体验
六、测试策略
6.1 测试环境配置
| 平台 | 测试工具 | 测试要点 |
|---|---|---|
| Android App | 真机调试 | 性能、兼容性、权限 |
| iOS App | 真机调试 | 性能、兼容性、权限 |
| 微信小程序 | 微信开发者工具 | 功能、样式、API |
| 支付宝小程序 | 支付宝开发者工具 | 功能、样式、API |
| H5 | Chrome DevTools | 响应式、兼容性 |
6.2 自动化测试
// 测试用例示例
describe('多端适配测试', () => {
it('登录功能各端一致', async () => {
// 测试登录逻辑在各端表现一致
})
it('支付功能各端可用', async () => {
// 测试支付功能在各端可用
})
})
七、发布流程
7.1 发布检查清单
- 条件编译代码正确
- 各端样式适配完成
- API 调用正常
- 支付功能测试通过
- 分包配置正确
- 包体积符合要求
7.2 发布渠道
| 平台 | 发布渠道 | 审核周期 |
|---|---|---|
| Android App | 应用商店 / 自有渠道 | 1-3天 |
| iOS App | App Store | 3-7天 |
| 微信小程序 | 微信审核 | 1-3天 |
| 支付宝小程序 | 支付宝审核 | 1-3天 |
| H5 | 自有服务器 | 即时 |
八、总结
推荐方案
单项目多端编译,利用 uni-app x 的跨端能力,通过条件编译处理平台差异。
关键点
- 使用条件编译处理平台差异
- 封装平台适配层统一 API 调用
- 合理使用分包控制包体积
- 建立完善的多端测试流程
后续优化
- 持续优化各端性能
- 完善自动化测试
- 建立多端 CI/CD 流程