CLI 快速上手
🎯 学习目标
5分钟内学会:
- 创建Flutter项目
- 理解BasePage架构
- 添加自己的页面
- 使用ViewModel管理状态
📦 安装
bash
npm install -g flu-cli🚀 创建第一个项目
bash
flu-cli new
# 按回车使用所有默认值,10秒完成!🏗️ 项目结构(Lite模板)
my_app/
├── lib/
│ ├── base/ # 基础框架
│ │ ├── base_page.dart
│ │ └── base_viewmodel.dart
│ ├── pages/ # 页面
│ │ └── home_page.dart
│ ├── viewmodels/ # 视图模型
│ │ └── home_viewmodel.dart
│ └── main.dart💡 核心概念
BasePage vs 普通StatefulWidget
| 传统方式 | flu-cli方式 | 优势 |
|---|---|---|
| 手动管理State | 自动监听ViewModel | 更简洁 |
| Widget+State双层 | Widget极简+State配置 | 更清晰 |
| 重复样板代码 | 统一架构 | 更高效 |
代码对比
传统StatefulWidget (繁琐):
dart
class HomePage extends StatefulWidget {
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _viewModel = HomeViewModel();
@override
void initState() {
super.initState();
_viewModel.addListener(() => setState(() {})); // 手动监听
}
@override
void dispose() {
_viewModel.removeListener(...); // 手动清理
_viewModel.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('首页')), // 重复代码
body: Text('${_viewModel.counter}'),
);
}
}flu-cli BasePage (简洁):
dart
class HomePage extends BasePage<HomeViewModel> {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends BasePageState<HomeViewModel, HomePage> {
@override
String get title => '首页'; // ← 配置在State层
@override
HomeViewModel createViewModel() => HomeViewModel();
@override
Widget buildContent(BuildContext context) {
return Text('${viewModel.counter}'); // ← 自动监听,无需setState
}
}关键差异:
- ✅ 无需手动监听ViewModel
- ✅ 无需手动dispose
- ✅ 无需重复Scaffold代码
- ✅ title等配置在State层,可访问viewModel
🎨 添加你的第一个页面
bash
cd my_app
flu-cli add page profile生成的代码:
dart
// lib/pages/profile_page.dart
class ProfilePage extends BasePage<ProfileViewModel> {
const ProfilePage({super.key});
@override
State<ProfilePage> createState() => _ProfilePageState();
}
class _ProfilePageState extends BasePageState<ProfileViewModel, ProfilePage> {
@override
String get title => 'Profile'; // ← 修改这里
@override
ProfileViewModel createViewModel() => ProfileViewModel();
@override
Widget buildContent(BuildContext context) {
return Center(
child: Text('Profile Page'), // ← 修改这里
);
}
}📊 ViewModel使用
ViewModel的作用: 管理页面状态和业务逻辑
dart
// lib/viewmodels/profile_viewmodel.dart
class ProfileViewModel extends ChangeNotifier {
String _name = 'John';
String get name => _name;
void updateName(String newName) {
_name = newName;
notifyListeners(); // ← 通知页面更新
}
}在页面中使用:
dart
@override
Widget buildContent(BuildContext context) {
return Column(
children: [
Text('Hello ${viewModel.name}'), // ← 直接访问
ElevatedButton(
onPressed: () => viewModel.updateName('Jane'), // ← 直接调用
child: Text('Change Name'),
),
],
);
}🔄 完整工作流
- 创建项目:
flu-cli new my_app - 添加页面:
flu-cli add page settings - 编辑ViewModel: 在
settings_viewmodel.dart中添加业务逻辑 - 编辑页面: 在
settings_page.dart中使用viewModel - 添加路由: 在
routes.dart中注册页面 - 运行:
flutter run
❓ 常见问题
Q: 什么时候用BasePage? A: 大部分页面都应该用。除非是特别简单的静态页面。
Q: 如何访问ViewModel? A: 在State中直接使用viewModel属性,已自动注入。
Q: title可以动态吗? A: 可以! String get title => viewModel.userName;
Q: 如何跳转页面? A: Navigator.pushNamed(context, '/settings')
Q: 支持哪些状态管理? A: Provider, GetX, 或原生ChangeNotifier。
🎯 下一步
恭喜! 你已经掌握了flu-cli的基础使用 🎉