掌握UniApp高级特性,实现一套代码多端完美适配
一、UniApp条件编译基础与核心语法
条件编译是UniApp实现跨平台开发的核心技术,它允许开发者在同一套代码中针对不同平台编写特定的逻辑和界面。
1.1 条件编译的基本语法结构
// 平台判断语法
#ifdef APP-PLUS
// 仅App端执行的代码
#endif
#ifndef H5
// 非H5平台执行的代码
#endif
// 多平台条件判断
#if defined(MP-WEIXIN) || defined(MP-ALIPAY)
// 微信小程序或支付宝小程序执行的代码
#endif
1.2 支持的条件编译平台标识
- APP-PLUS: App端(包含5+App和uni-app)
- APP-PLUS-NVUE: App nvue页面
- H5: H5端
- MP-WEIXIN: 微信小程序
- MP-ALIPAY: 支付宝小程序
- MP-BAIDU: 百度小程序
- MP-TOUTIAO: 字节跳动小程序
- MP-QQ: QQ小程序
二、模板中的条件编译实战
在模板中使用条件编译可以针对不同平台展示不同的UI界面和交互元素。
2.1 视图层条件编译示例
<template>
<view class="container">
<!-- 所有平台通用头部 -->
<view class="header">
<text>我的应用</text>
</view>
<!-- 平台特定内容 -->
<!-- #ifdef MP-WEIXIN -->
<view class="weixin-special">
<button open-type="share">微信分享</button>
<ad unit-id="weixin-ad-unit"></ad>
</view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="app-special">
<button @click="nativeFeature">调用原生功能</button>
<map style="width: 100%; height: 300rpx;"></map>
</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="h5-special">
<a href="/privacy" rel="external nofollow" >隐私政策</a>
<video src="/static/demo.mp4" controls></video>
</view>
<!-- #endif -->
<!-- 多平台条件判断 -->
<!-- #ifndef MP-WEIXIN -->
<view class="non-weixin">
<text>非微信小程序平台内容</text>
</view>
<!-- #endif -->
</view>
</template>
2.2 样式条件编译技巧
<style>
/* 通用样式 */
.container {
padding: 20rpx;
}
.header {
height: 80rpx;
background-color: #007AFF;
}
/* 平台特定样式 */
/* #ifdef MP-WEIXIN */
.weixin-special {
background-color: #07C160;
padding: 20rpx;
}
/* #endif */
/* #ifdef APP-PLUS */
.app-special {
background: linear-gradient(45deg, #FF3B30, #FF9500);
border-radius: 10rpx;
}
/* #endif */
/* #ifdef H5 */
.h5-special {
border: 2rpx solid #5856D6;
}
/* #endif */
</style>
三、JavaScript逻辑层条件编译深度应用
在JavaScript逻辑层使用条件编译可以处理不同平台的API差异和业务逻辑。
3.1 平台特定API调用
export default {
data() {
return {
platform: '',
userInfo: null
}
},
onLoad() {
this.detectPlatform();
this.initPlatformFeatures();
},
methods: {
detectPlatform() {
// #ifdef MP-WEIXIN
this.platform = '微信小程序';
// #endif
// #ifdef APP-PLUS
this.platform = 'App';
// #endif
// #ifdef H5
this.platform = 'H5';
// #endif
console.log(`当前平台: ${this.platform}`);
},
initPlatformFeatures() {
// #ifdef MP-WEIXIN
this.initWeixinSDK();
// #endif
// #ifdef APP-PLUS
this.initAppNative();
// #endif
// #ifdef H5
this.initH5Features();
// #endif
},
// 微信小程序特定功能
// #ifdef MP-WEIXIN
initWeixinSDK() {
wx.login({
success: (res) => {
if (res.code) {
console.log('微信登录code:', res.code);
this.weixinLogin(res.code);
}
}
});
},
weixinLogin(code) {
// 调用后端接口进行微信登录
uni.request({
url: 'https://api.example.com/weixin-login',
method: 'POST',
data: { code },
success: (res) => {
this.userInfo = res.data;
}
});
},
// #endif
// App端原生功能
// #ifdef APP-PLUS
initAppNative() {
// 获取设备信息
plus.device.getInfo({
success: (info) => {
console.log('设备信息:', info);
this.deviceInfo = info;
}
});
// 初始化推送
this.initPush();
},
initPush() {
uni.onPushMessage((res) => {
console.log('收到推送消息:', res);
this.showPushNotification(res);
});
},
nativeFeature() {
// 调用原生相机
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: (res) => {
console.log('拍照成功:', res.tempFilePaths[0]);
}
});
},
// #endif
// H5端特定功能
// #ifdef H5
initH5Features() {
// 初始化PWA功能
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('ServiceWorker 注册成功');
});
}
// 添加页面可见性监听
document.addEventListener('visibilitychange', this.handleVisibilityChange);
},
handleVisibilityChange() {
if (document.hidden) {
console.log('页面进入后台');
} else {
console.log('页面回到前台');
}
},
// #endif
// 通用分享功能(不同平台实现不同)
shareContent(shareInfo) {
// #ifdef MP-WEIXIN
wx.shareAppMessage({
title: shareInfo.title,
path: shareInfo.path,
imageUrl: shareInfo.imageUrl
});
// #endif
// #ifdef APP-PLUS
plus.share.sendWithSystem({
type: 'text',
content: shareInfo.content
});
// #endif
// #ifdef H5
if (navigator.share) {
navigator.share({
title: shareInfo.title,
text: shareInfo.content,
url: window.location.href
});
} else {
// 降级处理
this.fallbackShare(shareInfo);
}
// #endif
},
fallbackShare(shareInfo) {
// 通用的分享降级方案
uni.showModal({
title: '分享',
content: '请手动复制链接分享给好友',
showCancel: false
});
}
}
}
四、实战案例:多平台电商商品详情页开发
通过一个完整的电商商品详情页案例,展示条件编译在实际项目中的综合应用。
<template>
<view class="product-detail">
<!-- 商品图片区域 -->
<view class="image-section">
<swiper class="swiper" indicator-dots="true" autoplay="true">
<swiper-item v-for="(img, index) in product.images" :key="index">
<image :src="img" mode="aspectFill"></image>
</swiper-item>
</swiper>
</view>
<!-- 商品信息 -->
<view class="info-section">
<view class="price">¥{{product.price}}</view>
<view class="title">{{product.title}}</view>
<view class="description">{{product.description}}</view>
</view>
<!-- 平台特定的购买区域 -->
<!-- #ifdef MP-WEIXIN -->
<view class="purchase-weixin">
<button class="btn-buy" @click="weixinBuy">
立即购买
</button>
<button class="btn-cart" open-type="contact">
联系客服
</button>
</view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="purchase-app">
<view class="btn-group">
<button class="btn-add-cart" @click="addToCart">
加入购物车
</button>
<button class="btn-buy-now" @click="buyNow">
立即购买
</button>
</view>
<view class="safe-area"></view>
</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="purchase-h5">
<button class="btn-buy" @click="h5Buy">
立即购买
</button>
<view class="share-section">
<button @click="shareProduct">分享商品</button>
</view>
</view>
<!-- #endif -->
</view>
</template>
<script>
export default {
data() {
return {
product: {
id: 1,
title: '高端智能手机',
price: 5999,
description: '最新款旗舰手机,性能强劲,拍照出色',
images: [
'/static/product/1.jpg',
'/static/product/2.jpg',
'/static/product/3.jpg'
]
},
cartCount: 0
}
},
onLoad(options) {
this.productId = options.id;
this.loadProductDetail();
this.setNavigationBar();
},
onShareAppMessage() {
// #ifdef MP-WEIXIN
return {
title: this.product.title,
path: `/pages/product/detail?id=${this.productId}`,
imageUrl: this.product.images[0]
};
// #endif
},
methods: {
loadProductDetail() {
uni.request({
url: `https://api.example.com/products/${this.productId}`,
success: (res) => {
this.product = res.data;
},
fail: (error) => {
console.error('加载商品详情失败:', error);
this.showErrorToast();
}
});
},
setNavigationBar() {
// #ifdef APP-PLUS
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#FF3B30'
});
// #endif
// #ifdef H5
document.title = this.product.title;
// #endif
},
// 微信小程序购买逻辑
// #ifdef MP-WEIXIN
weixinBuy() {
wx.requestPayment({
timeStamp: '',
nonceStr: '',
package: '',
signType: 'MD5',
paySign: '',
success: (res) => {
uni.showToast({
title: '支付成功',
icon: 'success'
});
},
fail: (err) => {
uni.showToast({
title: '支付取消',
icon: 'none'
});
}
});
},
// #endif
// App端购买逻辑
// #ifdef APP-PLUS
addToCart() {
uni.showLoading({
title: '添加中...'
});
// 调用原生购物车动画
const animation = uni.createAnimation({
duration: 1000,
timingFunction: 'ease'
});
animation.translateY(-100).opacity(0).step();
this.animationData = animation.export();
setTimeout(() => {
uni.hideLoading();
this.cartCount++;
uni.showToast({
title: '添加成功',
icon: 'success'
});
}, 1000);
},
buyNow() {
uni.navigateTo({
url: `/pages/order/confirm?productId=${this.productId}`
});
},
// #endif
// H5端购买逻辑
// #ifdef H5
h5Buy() {
if (!this.checkLogin()) {
window.location.href = '/pages/login/index';
return;
}
// H5特定的支付流程
this.createH5Order();
},
createH5Order() {
uni.request({
url: 'https://api.example.com/orders/create',
method: 'POST',
data: {
productId: this.productId,
quantity: 1
},
success: (res) => {
if (res.data.paymentUrl) {
window.location.href = res.data.paymentUrl;
}
}
});
},
shareProduct() {
if (navigator.share) {
navigator.share({
title: this.product.title,
text: this.product.description,
url: window.location.href
});
} else {
this.showShareModal();
}
},
showShareModal() {
uni.showModal({
title: '分享商品',
content: '请复制链接分享给好友:' + window.location.href,
showCancel: false
});
},
// #endif
checkLogin() {
const token = uni.getStorageSync('token');
return !!token;
},
showErrorToast() {
uni.showToast({
title: '加载失败,请重试',
icon: 'none',
duration: 2000
});
}
}
}
</script>
五、条件编译最佳实践与性能优化
5.1 代码组织与维护策略
- 模块化条件编译:将平台特定代码抽离为独立模块
- 统一平台检测:封装平台检测工具函数
- 渐进式增强:从通用功能开始,逐步添加平台特性
5.2 性能优化建议
// 平台检测工具类
class PlatformUtils {
static isWeixin() {
// #ifdef MP-WEIXIN
return true;
// #endif
return false;
}
static isApp() {
// #ifdef APP-PLUS
return true;
// #endif
return false;
}
static isH5() {
// #ifdef H5
return true;
// #endif
return false;
}
static getPlatform() {
// #ifdef MP-WEIXIN
return 'weixin';
// #endif
// #ifdef APP-PLUS
return 'app';
// #endif
// #ifdef H5
return 'h5';
// #endif
return 'unknown';
}
}
// 使用示例
const platform = PlatformUtils.getPlatform();
console.log(`当前平台: ${platform}`);
if (PlatformUtils.isWeixin()) {
// 微信小程序特定逻辑
}
if (PlatformUtils.isApp()) {
// App端特定逻辑
}
六、总结
通过本文的深入学习,我们掌握了UniApp条件编译的核心技术和实战应用:
- 理解条件编译的基本语法和平台标识
- 掌握在模板、样式和逻辑层使用条件编译的技巧
- 学会处理不同平台的API差异和业务逻辑
- 通过实战案例掌握多平台适配的综合解决方案
- 了解代码组织和性能优化的最佳实践
条件编译是UniApp跨平台开发的核心武器,合理运用可以大大提高开发效率和代码质量。
// 页面交互功能
document.addEventListener(‘DOMContentLoaded’, function() {
// 为代码块添加交互功能
const codeBlocks = document.querySelectorAll(‘pre code’);
codeBlocks.forEach(block => {
// 添加点击复制功能
block.addEventListener(‘click’, function() {
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(this);
selection.removeAllRanges();
selection.addRange(range);
try {
document.execCommand(‘copy’);
const originalText = this.textContent;
this.textContent = ‘代码已复制!’;
setTimeout(() => {
this.textContent = originalText;
}, 1500);
} catch (err) {
console.log(‘复制失败:’, err);
}
selection.removeAllRanges();
});
block.style.cursor = ‘pointer’;
block.title = ‘点击选择并复制代码’;
});
// 添加章节导航
const sections = document.querySelectorAll(‘section’);
sections.forEach((section, index) => {
section.id = `section-${index + 1}`;
});
});

