做移动端开发,最纠结的往往不是写代码,而是 “选技术栈”。
老板想要 iOS 和 Android 双端,运营想要微信小程序,产品想要丝滑的动画,而开发团队可能只有三两个人。这时候,UniApp 和 Flutter 这两位跨平台界的“顶流”选手就一定会进入你的视野。
它们各有千秋,也各有“坑”。光说不练假把式,今天咱们不仅聊理论,还直接上代码。通过实现同一个“商品列表页”,让你直观感受两者的编码风格差异,帮你做出最务实的选择。
🟢 UniApp:前端开发者的“瑞士军刀”
如果你是 Vue.js 的老玩家,UniApp 对你来说就像回家一样亲切。它由 DCloud 团队推出,核心卖点就是一个字:快。
为什么选它?
上手零门槛: 只要你会 Vue,你就会 UniApp。
真·一套代码通吃: 不仅是 App,还能编译成微信小程序、H5 等。如果你的业务极其依赖小程序生态,选它准没错。
- 💻 代码实战:UniApp 实现列表页 UniApp 采用的是经典的 Template (结构) + Script (逻辑) + Style (样式) 分离模式。
HTML
<!-- index.vue -->
<template>
<view class="container">
<!-- 列表循环 -->
<view class="list-item" v-for="(item, index) in productList" :key="index" @click="openDetail(item)">
<image :src="item.image" class="cover"></image>
<view class="info">
<text class="title">{{ item.name }}</text>
<text class="price">¥ {{ item.price }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
productList: [
{ name: '发动机外壳', price: 299, image: '/static/k1.png' },
{ name: '牛皮的鼠标', price: 1299, image: '/static/c1.png' }
]
}
},
methods: {
openDetail(item) {
uni.showToast({ title: '选中了: ' + item.name, icon: 'none' });
}
}
}
</script>
<style>
/* 熟悉的 CSS 写法 */
.list-item { display: flex; padding: 10px; border-bottom: 1px solid #eee; }
.info { display: flex; flex-direction: column; margin-left: 10px; }
.title { font-size: 16px; font-weight: bold; }
.price { color: #ff0000; margin-top: 5px; }
</style>
👀 观感: 是不是和写网页一模一样?标签是 <view> 和 <image>,逻辑是标准的 JS/TS,样式是 CSS。对于前端同学来说,完全没有认知负担。
🔵 Flutter:Google 亲儿子的“降维打击”
Flutter 是 Google 拿出的重型武器。它不依赖系统的原生控件,而是自己带了一个高性能渲染引擎(Skia/Impeller),把 UI 像画画一样画出来。
为什么选它?
性能怪兽: 60帧甚至120帧不在话下,性能无限逼近原生。
UI 高度统一: 因为是自绘 UI,不用担心不同手机系统控件长得不一样,设计师狂喜。
- 💻 代码实战:Flutter 实现列表页 Flutter 使用 Dart 语言,采用“万物皆 Widget(组件)”的思想,UI 结构和逻辑是写在一起的(声明式 UI)。
Dart
// main.dart
import 'package:flutter/material.dart';
class ProductListPage extends StatelessWidget {
// 数据源
final List<Map<String, dynamic>> productList = [ {'name': '发动机外壳', 'price': 299, 'image': 'assets/k1.png'}, {'name': '牛皮的鼠标', 'price': 1299, 'image': 'assets/c1.png'}, ];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("商品列表")),
body: ListView.builder( // 构建列表
itemCount: productList.length,
itemBuilder: (context, index) {
final item = productList[index];
return InkWell( // 点击事件
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('选中了: ${item['name']}')),
);
},
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.grey[200]!))
),
child: Row( // 布局:水平排列
children: [
Image.asset(item['image'], width: 60, height: 60),
SizedBox(width: 10), // 间距
Column( // 布局:垂直排列
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(item['name'], style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(height: 5),
Text("¥ ${item['price']}", style: TextStyle(color: Colors.red)),
],
)
],
),
),
);
},
),
);
}
}
👀 观感: 代码层级较深(俗称“嵌套地狱”),样式不是写在 CSS 里,而是作为参数传给 Widget(比如 TextStyle、Container)。这需要适应一种“搭积木”的思维方式。但好处是,类型安全极其强大,编辑器智能提示非常爽。
📝 灵魂拷问:到底选谁?
看完代码,相信你心里已经有点数了。我们再总结一下:
- ✅ 选 UniApp,如果: 团队基因是 Web 前端: 大家都是 Vue 熟手,不想学 Dart,上手即巅峰。
必须覆盖小程序: 业务极其依赖微信/支付宝小程序引流,且顺带需要打包 App。
项目追求短平快: 外包项目、活动页、信息展示类应用,要求快速上线。
- ✅ 选 Flutter,如果: 追求极致体验: App 需要复杂的交互动画, 或者对 UI 的精致程度有极高要求(如金融、电商大厂App)。
不需要小程序: 或者小程序是独立开发的,App 这边只需要专注 iOS 和 Android 双端。
长期维护的大型项目: Dart 强类型的特性,让代码在项目变大后更容易维护和重构。
- 最后总结一句: 技术是为业务服务的。如果你的目标是**“快”且“全”,UniApp 是你的好帮手;如果你的目标是“精”且“稳”**,Flutter 值得你投入。
- 微信公众号: