写两套App界面太折腾:Flutter、React Native与鸿蒙ArkUI跨平台UI开发真实项目踩坑与选型指南
一、先从一个真实场景说起
去年我们团队接了个电商App项目,客户说”要同时上iOS和安卓,预算有限,能不能少招两个人”。我当时的第一反应是:这不就是跨平台技术该大显身手的时候了嘛!
结果呢?项目做了八个月,跨平台方案翻车三次,最后iOS和安卓两套代码还是得维护,还额外加了套鸿蒙版……整个人都不好了。
今天我想把这些坑都摊开来说,希望后来的朋友能少走弯路。
二、为什么”两套开发”这么折腾?
先别急着上跨平台方案,咱们先把痛点讲清楚。
场景一:需求变更是常态
产品说”这个按钮要改颜色”,iOS开发改一行,安卓开发改一行。两个平台的人沟通成本、时间成本加起来,远比一个跨平台团队大。
场景二:UI细节对不齐
iOS用Auto Layout,安卓用ConstraintLayout,鸿蒙又是一种新的声明式语法。同一个设计稿,三个平台实现出来总有些微差异,测试阶段天天被产品怼”这怎么跟设计不一样”。
场景三:维护成本翻倍
发现了一个bug?iOS和安卓各修一次。加了一个新功能?两边都得写。人员流动?iOS走了招一个,安卓走了再招一个。
场景四:性能瓶颈各自为战
iOS用Swift/Objective-C写的原生视图,安卓用Kotlin/Java写的原生视图。同一个列表滚动,iOS那边流畅得像丝绸,安卓那边却卡顿得像拖拉机——然后两边的优化工作得分别做,谁也不知道对方的问题出在哪。
说真的,如果你是个小团队,上面这些痛点每一个都能让你半夜睡不着觉。
三、跨平台技术的三大主流选手
3.1 Flutter:Google的”一次性写完,处处运行”
Flutter是Google在2017年推出的开源UI框架,它的核心理念是:“Write Once, Run Anywhere”,而且它用Dart语言。
Flutter的工作原理
Flutter和传统的WebView方案完全不同。它不依赖系统自带的UI组件,而是自己绘制每一个像素。你可以把它想象成一个游戏引擎——Unity也能渲染3D画面,Flutter也能渲染2D/3D界面。
┌─────────────────────────────────────┐
│ Dart 代码层 │
│ MaterialApp / StatefulWidget │
├─────────────────────────────────────┤
│ Flutter Framework │
│ (Widget树 / RenderObject树) │
├─────────────────────────────────────┤
│ Skia / Impeller 渲染引擎 │
│ (自绘UI,不依赖系统原生控件) │
├─────────────────────────────────────┤
│ iOS (Metal) / Android (OpenGL) │
└─────────────────────────────────────┘
一个典型的Flutter组件长这样:
// 一个简单的按钮组件
class CustomButton extends StatelessWidget {
final String text;
final VoidCallback onTap;
const CustomButton({
Key? key,
required this.text,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onTap,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
padding: const EdgeInsets.symmetric(
horizontal: 32,
vertical: 16,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Text(
text,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
);
}
}
这个按钮在iOS和安卓上跑出来,外观和行为是完全一致的。Flutter会用Dart编译器把代码编译成原生ARM代码,然后在设备上直接运行。
Flutter的优点:
- 性能接近原生:因为它是自绘渲染,不依赖系统控件,所以表现非常稳定
- UI一致性极高:同一个Widget,在任何设备上渲染出来的效果几乎一样
- 热重载功能强大:改完代码,保存一下,界面上立即可见变化,效率超高
- 生态丰富:pub.dev上有数万个开源包,从动画、网络到本地存储应有尽有
- Google背书:大厂支持,长期维护有保障
Flutter的坑(也是真的多):
- 包体积偏大:Flutter自带的引擎就要占几MB,对于要求包体积极小的场景不太友好
- Dart语言学习成本:虽然Dart和Java/JavaScript有点像,但语法细节还是需要适应
- 原生混合开发复杂:如果你的项目需要大量调用原生API,桥接层的调试会比较痛苦
- 鸿蒙支持滞后:Flutter对鸿蒙的适配还在进行中,现阶段如果想做鸿蒙版,还是得用其他方案
3.2 React Native:Facebook的”用JavaScript写原生”
React Native是Meta(Facebook)推出的跨平台框架,核心理念是:“Learn Once, Write Anywhere”。
React Native的工作原理
和Flutter完全不同,React Native不会自绘UI。它用的是系统自带的原生组件——在iOS上就是UIKit,在安卓上就是Android View。React Native通过一个JavaScript运行时(Hermes引擎)和原生层进行通信。
┌─────────────────────────────────────┐
│ JavaScript / TypeScript │
│ (React组件 / hooks / state) │
├─────────────────────────────────────┤
│ React Native Bridge │
│ (异步通信 / 同步调用) │
├─────────────────────────────────────┤
│ iOS (UIKit) / Android (View) │
│ (使用系统原生组件渲染) │
└─────────────────────────────────────┘
一个典型的React Native组件长这样:
// 同样的一个按钮组件
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
const CustomButton = ({ text, onPress }) => {
return (
<TouchableOpacity
style={styles.button}
onPress={onPress}
activeOpacity={0.8}
>
<Text style={styles.buttonText}>{text}</Text>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
button: {
backgroundColor: '#2196F3',
paddingHorizontal: 32,
paddingVertical: 16,
borderRadius: 8,
alignItems: 'center',
},
buttonText: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: 'bold',
},
});
export default CustomButton;
看起来像JavaScript?没错,但它渲染出来的是真正的原生按钮,而不是一个WebView里的网页。
React Native的优点:
- 开发团队熟悉度高:前端团队用JavaScript/TypeScript就能上手,学习曲线相对平缓
- 包体积较小:没有自带渲染引擎,只打包业务代码
- 社区极其庞大:npm上资源无数,几乎你想到的功能都有现成包
- 热更新能力:可以通过CodePush等方式绕过应用商店审核,直接推送更新
- 与Web技术栈互通:同一套逻辑可以同时跑在Web端(React Native for Web)
React Native的坑(也不少):
- Bridge性能瓶颈:JavaScript和原生层通信有延迟,复杂动画和大量数据交互时容易卡顿
- UI一致性挑战:因为用的是系统原生组件,iOS和安卓的表现会有细微差异,需要额外处理
- 原生模块依赖:某些高级功能(如蓝牙、AR)需要写原生代码,调试复杂
- 升级成本高:React Native版本升级经常带来breaking changes,升级痛苦指数较高
- 鸿蒙适配困难:React Native目前对鸿蒙的支持非常有限,基本可以认为不支持
3.3 鸿蒙ArkUI:华为的”一套代码,全场景覆盖”
ArkUI是华为为鸿蒙系统开发的UI框架,核心理念是:“一次开发,多端部署”。
ArkUI的工作原理
ArkUI采用声明式编程范式,和Flutter、React Native都有相似之处,但它深度集成鸿蒙系统,支持一次开发、多端部署(手机、平板、手表、智慧屏、车机等多种设备)。
┌─────────────────────────────────────┐
│ ArkTS / ArkUI 代码层 │
│ (声明式UI / 组件化) │
├─────────────────────────────────────┤
│ ArkUI 框架层 │
│ (组件树 / 状态管理 / 事件系统) │
├─────────────────────────────────────┤
│ Ark Compiler 编译器 │
│ (AOT预编译 / JIT即时编译) │
├─────────────────────────────────────┤
│ 鸿蒙系统 Native层 │
│ (ArkUI渲染引擎 / 系统服务) │
└─────────────────────────────────────┘
一个典型的ArkUI组件长这样:
// 同样的一个按钮组件
@Component
struct CustomButton {
@Prop text: string = '';
@Prop onClick: () => void = () => {};
build() {
Button(this.text)
.backgroundColor('#2196F3')
.padding({ left: 32, right: 32, top: 16, bottom: 16 })
.borderRadius(8)
.onClick(() => {
this.onClick();
})
}
}
看起来简洁多了对吧?ArkUI用的是ArkTS语言(TypeScript的超集),配合声明式语法,写起来非常直观。
ArkUI的优点:
- 全场景覆盖:不仅仅是手机和平板,还包括手表、智慧屏、车机、IoT设备,真正的一次开发多端部署
- 性能优异:鸿蒙系统的Ark Compiler采用AOT预编译,启动速度和运行时性能都非常好
- 与鸿蒙生态深度集成:鸿蒙的分布式能力、设备协同、隐私安全等特性可以直接调用
- 国内政策支持:随着鸿蒙生态的快速发展,未来在华为系设备上会有更多原生支持和优化
- 学习成本适中:TypeScript语法的开发者上手非常快
ArkUI的坑(现阶段确实存在):
- 生态尚在建设中:相比Flutter和React Native,HarmonyOS的第三方库相对较少,某些特定功能可能需要自己实现
- 跨平台范围有限:目前主要覆盖华为鸿蒙设备,如果要同时支持iOS和安卓,还是需要其他方案配合
- 文档和教程资源相对较少:虽然官方文档在快速完善,但社区资源相比前两者仍有差距
- 开发工具链仍在迭代:DevEco Studio的体验虽然不错,但偶尔会有一些小bug和优化空间
- 鸿蒙外平台支持有限:如果产品需要同时上架App Store和Play Store,ArkUI不是最优解
四、真实项目中的踩坑血泪史
4.1 Flutter项目的五个大坑
坑一:平台通道(Platform Channel)调试地狱
我们的电商App需要调用原生的支付SDK。Flutter代码写得顺风顺水,但一联调支付,iOS和安卓的回调行为完全不一样。
// Flutter端代码
static const platform = MethodChannel('com.example/payment');
Future<void> pay() async {
try {
final result = await platform.invokeMethod('pay', {
'amount': 99.99,
'orderId': 'ORD123456',
});
print('支付结果: $result');
} catch (e) {
print('支付失败: $e');
}
}
// 安卓端原生代码
class PaymentHandler : MethodChannel.MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
if (call.method == "pay") {
val amount = call.argument<Double>("amount")
val orderId = call.argument<String>("orderId")
// 模拟支付
Handler(Looper.getMainLooper()).post {
result.success("SUCCESS")
}
} else {
result.notImplemented()
}
}
}
问题出在哪?安卓端用的是主线程回调,iOS端用的是子线程回调。结果在安卓上支付成功回调正常触发,在iOS上回调偶尔丢失——因为iOS那边忘了切回主线程。
教训:所有Platform Channel的回调都必须切回主线程!
坑二:ListView性能灾难
我们的商品列表页有1000+商品,用了ListView.builder,在低端安卓机上滑动卡顿严重。
// 错误的写法:列表项过于复杂
ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ProductCard(
product: products[index],
// ProductCard内部有图片、动画、复杂布局
);
},
)
后来我们优化了:
// 优化1:使用ListView.builder + RepaintBoundary
ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return RepaintBoundary(
child: ProductCard(product: products[index]),
);
},
)
// 优化2:图片使用cached_network_image + 缓存策略
CachedNetworkImage(
imageUrl: product.imageUrl,
placeholder: (context, url) => Container(
color: Colors.grey[200],
child: const Center(child: CircularProgressIndicator()),
),
errorWidget: (context, url, error) => const Icon(Icons.error),
memCacheWidth: 200, // 限制内存缓存尺寸
imageCacheSize: 200, // 限制缓存图片数量
)
教训:复杂列表页一定要做性能优化,RepaintBoundary和图片缓存是必选项。
坑三:iOS上字体渲染差异
设计稿用的字体在安卓上显示完美,在iOS上却”变胖”了。原因是iOS和安卓的字体渲染引擎不同,同一行文字在两个平台上的行高不一致。
// 解决:手动设置行高和字重
Text(
product.name,
style: TextStyle(
fontFamily: 'CustomFont',
fontSize: 16,
height: 1.2, // 手动控制行高
fontWeight: FontWeight.w500,
),
)
教训:跨平台字体渲染必须手动调整,不能指望自动一致。
坑四:暗黑模式适配遗漏
产品上线后,用户反馈在暗黑模式下某些文字看不清楚。查代码发现,我们用的是硬编码颜色值:
// ❌ 错误写法:硬编码颜色
Container(
color: Colors.white,
child: Text(
'标题',
style: TextStyle(color: Colors.black),
),
)
// ✅ 正确写法:使用Theme
Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: Text(
'标题',
style: TextStyle(
color: Theme.of(context).textTheme.bodyLarge?.color,
),
),
)
教训:所有颜色必须通过Theme获取,否则暗黑模式一定会出bug。
坑五:状态管理选型失误
项目初期我们用了简单的setState管理状态,后来业务复杂了,状态到处飞,改一个数据要追十几层代码。最终迁移到Riverpod,重构工作量巨大。
// ❌ 错误:setState层层传递
class ProductPage extends StatefulWidget {
@override
_ProductPageState createState() => _ProductPageState();
}
class _ProductPageState extends State<ProductPage> {
int cartCount = 0;
void addToCart() {
setState(() {
cartCount++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('购物车: $cartCount'), // 整个页面重建
),
body: ProductList(onAddToCart: addToCart),
);
}
}
// ✅ 正确:使用Riverpod
@riverpod
class CartNotifier extends _$CartNotifier {
@override
int build() => 0;
void increment() => state++;
}
// 使用
Consumer(
builder: (context, watch, child) {
final cartCount = watch(cartNotifierProvider);
return Text('购物车: $cartCount');
},
)
教训:项目一开始就选对状态管理方案,后期重构成本极高。
4.2 React Native项目的四个大坑
坑一: Hermes引擎内存泄漏
我们的App在安卓低端机上运行一段时间后会出现OOM(内存溢出)崩溃。排查后发现是Hermes引擎的GC(垃圾回收)在特定场景下没有正确回收闭包引用的对象。
// 容易出问题的代码模式
useEffect(() => {
const subscription = eventEmitter.addListener('update', (data) => {
// 这里引用了component的state,容易导致循环引用
setState({ ...state, data });
});
return () => {
subscription.remove();
// 但eventEmitter本身的引用可能被缓存,导致无法GC
};
}, []);
解决方案是用useRef替代useState来存储中间数据,并且确保所有事件监听都在清理函数中正确移除。
坑二:Android上的ScrollView嵌套问题
我们的商品详情页有个长页面,里面嵌套了横向滚动和纵向滚动的区域。在iOS上表现正常,在安卓上滑动经常出现冲突。
// 解决方案:使用react-native-gesture-handler
import { GestureHandlerRootView } from 'react-native-gesture-handler';
// 在根组件包裹
<GestureHandlerRootView style={{ flex: 1 }}>
<App />
</GestureHandlerRootView>
// 使用NativeScrollView替代原生ScrollView
import { NativeScrollView } from 'react-native-gesture-handler';
坑三:原生模块编译失败
我们的项目用了一个第三方原生模块(蓝牙通信),在Android 14上编译失败。排查后发现是该模块用了已废弃的Android API。
// build.gradle中的配置
android {
compileSdkVersion 34
defaultConfig {
minSdkVersion 21
targetSdkVersion 34
// 关键:关闭自动升级compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
}
教训:第三方原生模块升级需要格外小心,最好锁定版本。
坑四:iOS Build时间过长
我们的React Native项目每次iOS Build都要15分钟以上,严重拖慢开发效率。
解决方案:
# Podfile中启用cocoapods-deintegrate和优化
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym'
end
end
end
同时把Hermes引擎预编译,避免每次构建都重新编译JS代码。
4.3 鸿蒙ArkUI项目的三个大坑
坑一:动画性能不稳定
我们的登录页面有个渐变动画,在华为手机P40上运行流畅,但在畅享系列低端机上帧率掉到30fps以下。
// 优化前:复杂的链式动画
@State opacity: number = 0;
@State translateY: number = 50;
build() {
Column() {
Text('欢迎来到我们的App')
.opacity(this.opacity)
.translate({ x: 0, y: this.translateY })
}
.onAppear(() => {
animateTo({
duration: 1000,
curve: Curve.EaseOut
}, () => {
this.opacity = 1;
this.translateY = 0;
});
})
}
// 优化后:简化动画,使用requestFrame动画
@State progress: number = 0;
build() {
Column() {
Text('欢迎来到我们的App')
.opacity(this.progress)
.translate({ x: 0, y: 50 * (1 - this.progress) })
}
.onAppear(() => {
this.startAnimation();
})
}
async startAnimation() {
const startTime = performance.now();
const duration = 1000;
const animate = () => {
const elapsed = performance.now() - startTime;
this.progress = Math.min(elapsed / duration, 1);
if (this.progress < 1) {
requestFrame(animate);
}
};
requestFrame(animate);
}
教训:低端设备上要避免复杂的链式动画,手动控制帧率更可控。
坑二:鸿蒙设备碎片化适配
华为的设备太多了——手机、平板、手表、智慧屏、车机……每种设备的屏幕尺寸、分辨率、交互方式都不一样。
// 使用响应式布局适配不同设备
@Entry
@Component
struct LoginView {
@State screenWidth: number = 0;
@State screenHeight: number = 0;
aboutToAppear() {
const windowClass = window.getWindowSize();
this.screenWidth = windowClass.width;
this.screenHeight = windowClass.height;
}
build() {
Stack() {
// 背景图自适应
Image($r('app.media.login_bg'))
.width('100%')
.height('100%')
.objectFit(ImageFit.Cover)
// 登录表单,根据屏幕尺寸调整
Column() {
// 手机和平板的布局差异
if (this.screenWidth > 600) {
// 平板布局:左右分栏
Row() {
Column() {
// 左侧品牌展示
}.layoutWeight(1)
Column() {
// 右侧登录表单
LoginForm()
}.layoutWeight(1)
}
} else {
// 手机布局:上下排列
Column() {
// 顶部品牌展示
BrandHeader()
// 底部登录表单
LoginForm()
}
}
}
.width('100%')
.height('100%')
}
.width('100%')
.height('100%')
}
}
教训:鸿蒙开发必须考虑多设备适配,响应式布局是必备技能。
坑三:鸿蒙包体积控制
我们的第一个鸿蒙版本包体积达到了120MB,远超预期的80MB。
排查后发现是两个问题:
- 资源文件没有压缩
- 第三方库引入了大量未使用的代码
// oh-package.json5中的优化配置
{
"name": "my-app",
"version": "1.0.0",
"description": " MyApp",
"main": "",
"author": "",
"license": "Apache-2.0",
"dependencies": {
"@ohos/crypto-js": "^1.0.0"
},
"devDependencies": {
"@ohos/hypium": "1.0.6"
},
"dynamicDependencies": {},
"overrides": {}
}
解决方案:
- 使用
ohpm的tree-shaking功能 - 对图片资源进行压缩(使用cwebp工具转换为WebP格式)
- 移除未使用的第三方库
五、三大技术栈的深度对比
| 对比维度 | Flutter | React Native | ArkUI (鸿蒙) |
|---|---|---|---|
| 语言 | Dart | JavaScript/TypeScript | ArkTS (TypeScript超集) |
| 渲染方式 | 自绘(Skia/Impeller) | 原生组件 | 原生组件 |
| 性能 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| UI一致性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| 学习曲线 | 中等 | 较低(前端友好) | 中等 |
| 包体积 | 偏大(约15-20MB起步) | 较小 | 中等 |
| 热更新 | 支持(需合规) | 支持(CodePush) | 支持(华为热修复) |
| iOS支持 | ✅ 优秀 | ✅ 优秀 | ❌ 不支持 |
| Android支持 | ✅ 优秀 | ✅ 优秀 | ❌ 不支持 |
| 鸿蒙支持 | ⚠️ 有限 | ❌ 不支持 | ✅ 原生支持 |
| 社区生态 | 非常成熟 | 极其成熟 | 快速发展中 |
| 企业支持 | Meta | 华为 | |
| 适合场景 | 多平台一致性要求高 | 前端团队转型 | 鸿蒙生态优先 |
六、选型决策树:你的项目该怎么选?
场景一:只做鸿蒙设备,面向国内市场
首选:ArkUI
理由:
- 鸿蒙生态政策支持力度大
- 华为设备覆盖广泛(手机、平板、手表、车机)
- 开发效率在鸿蒙设备上最高
- 未来鸿蒙设备的市场占有率会持续提升
补充方案:如果需要同时支持iOS/安卓,可以Flutter + ArkUI组合,或者React Native + ArkUI组合。
场景二:同时支持iOS和安卓,不做鸿蒙
首选:Flutter(推荐)或 React Native
- 追求UI一致性和性能 → Flutter
- 前端团队转型、追求开发效率 → React Native
我们的电商App最终选择了Flutter,因为产品对UI一致性要求极高,每个按钮、每个动画都必须严格按照设计稿执行。Flutter的自绘引擎完美解决了这个问题。
场景三:同时支持iOS、安卓和鸿蒙
推荐方案:Flutter + ArkUI混合开发
这是目前比较成熟的方案:
- Flutter负责iOS和安卓版本
- ArkUI负责鸿蒙版本
- 业务逻辑通过共享库(Dart Library / ArkTS Library)复用
项目结构:
my-app/
├── flutter_app/ # Flutter项目(iOS + Android)
│ ├── lib/
│ │ ├── core/ # 共享核心逻辑
│ │ ├── features/ # 业务功能模块
│ │ └── main.dart
│ └── pubspec.yaml
│
├── harmony_app/ # 鸿蒙项目
│ ├── entry/src/main/ets/
│ │ ├── core/ # 共享核心逻辑(ArkTS)
│ │ ├── features/ # 业务功能模块
│ │ └── pages/
│ └── oh-package.json5
│
└── shared/ # 共享数据模型和接口定义
├── product.model.ts
├── api.service.ts
└── types.ts
替代方案:React Native + ArkUI混合开发
如果团队有React技术栈基础,也可以选React Native + ArkUI组合,但要注意React Native在鸿蒙上的适配工作量大。
场景四:Web端也需要支持
推荐:React Native + React Native for Web
或者直接用Flutter Web(但体验不如React方案)。
七、团队能力匹配:人比技术更重要
选技术栈不能只看技术本身,团队的能力匹配才是关键。
如果你的团队:
- 前端背景为主 → React Native上手最快,TypeScript无缝衔接
- iOS/安卓原生背景为主 → Flutter学习曲线更平缓,Dart和Swift/Kotlin有相似之处
- 鸿蒙开发团队 → ArkUI是必选项,没有备选
- 全栈团队 → Flutter灵活性最高,团队可以根据需求自由扩展
人员成本对比(估算):
| 技术栈 | iOS开发成本 | 安卓开发成本 | 鸿蒙开发成本 | 总成本 |
|---|---|---|---|---|
| 原生双端 | 高 | 高 | - | 最高 |
| Flutter双端 | 中 | 中 | - | 中 |
| RN双端 | 中 | 中 | - | 中 |
| Flutter+ArkUI | 中 | 中 | 低 | 中高 |
| RN+ArkUI | 中 | 中 | 低 | 中高 |
八、我的真实建议
2024-2026年的选型建议:
- 鸿蒙设备为主 → 坚定不移选ArkUI
- iOS+安卓双端 → Flutter优先,React Native次之
- 三端全覆盖 → Flutter + ArkUI混合方案
- 已有React技术栈 → React Native + ArkUI混合方案
避坑清单:
- ✅ 项目初期就选好状态管理方案,别等到后期重构
- ✅ 所有颜色、字体通过Theme统一管理
- ✅ 列表页一定要做性能优化(虚拟列表、图片缓存)
- ✅ 第三方库选型要慎重,优先选活跃维护的
- ✅ 鸿蒙项目一定要做多设备适配测试
- ✅ 跨平台方案的兼容性测试要覆盖主流机型
最后说一句:
没有完美的技术栈,只有最适合你项目的方案。我们团队踩过Flutter的坑,也试过React Native的坑,最后选了混合方案。如果你现在问我”选哪个”,我会说:先想清楚你的用户在哪,再决定技术选型。
如果你的用户主要是华为手机用户,别犹豫,ArkUI。 如果你的用户遍布iOS和安卓,Flutter是稳妥的选择。 如果你的团队是前端出身,React Native会让你更舒服。
技术是工具,不是目的。解决问题才是根本。
希望这篇文章能帮到正在纠结的你。如果有什么具体问题,欢迎在评论区交流,我们一起探讨。