Skip to content

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'),
      ),
    ],
  );
}

🔄 完整工作流

  1. 创建项目: flu-cli new my_app
  2. 添加页面: flu-cli add page settings
  3. 编辑ViewModel: 在settings_viewmodel.dart中添加业务逻辑
  4. 编辑页面: 在settings_page.dart中使用viewModel
  5. 添加路由: 在routes.dart中注册页面
  6. 运行: 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的基础使用 🎉

Released under the MIT License.