Skip to content

生成文件

本指南详细介绍如何使用 Flu CLI VSCode 扩展生成各种类型的文件。

生成方式

扩展提供 2 种生成文件的方式:

方式 1:右键菜单(推荐)⭐

  1. 在资源管理器中,右键点击目标文件夹
  2. 选择 Flu: 生成文件(或 Flu: Generate
  3. 选择要生成的文件类型
  4. 按照提示完成生成

优点

  • 所见即所得,直接在目标位置生成
  • 无需手动输入路径
  • 操作直观

方式 2:命令面板

  1. 打开命令面板(Cmd+Shift+P / Ctrl+Shift+P
  2. 输入 Flu: Generate
  3. 选择目标文件夹
  4. 选择文件类型
  5. 按照提示完成生成

支持的文件类型

扩展支持生成以下类型的文件:

类型说明生成文件
Page页面文件Page + ViewModel
ViewModel视图模型ViewModel
Widget通用组件Widget
Component业务组件Component
Model数据模型Model
Service服务类Service
Module完整模块完整目录结构

Page(页面)

生成步骤

  1. 右键点击 pages 文件夹
  2. 选择 Flu: 生成文件
  3. 选择 Page
  4. 输入页面名称(如 home
  5. 选择页面类型:
    • Stateful Widget:有状态组件(推荐)
    • Stateless Widget:无状态组件

生成文件

lib/features/home/pages/
└── home_page.dart

lib/features/home/viewmodels/
└── home_viewmodel.dart

生成内容

home_page.dart(Stateful):

dart
import 'package:flutter/material.dart';
import '../viewmodels/home_viewmodel.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late final HomeViewModel _viewModel;

  @override
  void initState() {
    super.initState();
    _viewModel = HomeViewModel();
  }

  @override
  void dispose() {
    _viewModel.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Container(),
    );
  }
}

home_viewmodel.dart

dart
import 'package:flutter/foundation.dart';

class HomeViewModel extends ChangeNotifier {
  // 状态
  bool _isLoading = false;
  bool get isLoading => _isLoading;

  // 初始化
  Future<void> init() async {
    // TODO: 初始化逻辑
  }

  // 业务逻辑
  Future<void> loadData() async {
    _isLoading = true;
    notifyListeners();

    try {
      // TODO: 加载数据
    } catch (e) {
      debugPrint('Error: $e');
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  @override
  void dispose() {
    // TODO: 清理资源
    super.dispose();
  }
}

配置选项

.flu-cli.json 中配置 Page 生成器:

json
{
    "generators": {
        "page": {
            "path": "lib/pages", // 生成路径
            "defaultType": "stateful", // 默认类型:stateful | stateless
            "withViewModel": true, // 是否生成 ViewModel
            "withBasePage": false, // 是否继承 BasePage
            "basePageClass": "BasePage", // BasePage 类名
            "basePageImport": "package:my_app/core/base/base_page.dart",
            "fileSuffix": "_page" // 文件后缀
        }
    }
}

使用场景

  • 创建新的页面
  • 需要独立的业务逻辑
  • 需要状态管理

ViewModel(视图模型)

生成步骤

  1. 右键点击 viewmodels 文件夹
  2. 选择 Flu: 生成文件
  3. 选择 ViewModel
  4. 输入名称(如 user

生成文件

lib/features/user/viewmodels/
└── user_viewmodel.dart

生成内容

dart
import 'package:flutter/foundation.dart';

class UserViewModel extends ChangeNotifier {
  // 状态
  bool _isLoading = false;
  bool get isLoading => _isLoading;

  // 初始化
  Future<void> init() async {
    // TODO: 初始化逻辑
  }

  // 业务逻辑
  Future<void> loadData() async {
    _isLoading = true;
    notifyListeners();

    try {
      // TODO: 加载数据
    } catch (e) {
      debugPrint('Error: $e');
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  @override
  void dispose() {
    // TODO: 清理资源
    super.dispose();
  }
}

配置选项

json
{
    "generators": {
        "viewModel": {
            "path": "lib/viewmodels",
            "withBaseViewModel": false, // 是否继承 BaseViewModel
            "baseViewModelClass": "BaseViewModel",
            "baseViewModelImport": "package:my_app/core/base/base_viewmodel.dart",
            "fileSuffix": "_viewmodel"
        }
    }
}

使用场景

  • 单独创建 ViewModel
  • 复用业务逻辑
  • 多个页面共享同一个 ViewModel

Widget(通用组件)

生成步骤

  1. 右键点击 widgets 文件夹
  2. 选择 Flu: 生成文件
  3. 选择 Widget
  4. 输入组件名称(如 custom_button
  5. 选择组件类型:
    • Stateful Widget
    • Stateless Widget(推荐)

生成文件

lib/shared/widgets/
└── custom_button.dart

生成内容

custom_button.dart(Stateless):

dart
import 'package:flutter/material.dart';

class CustomButton extends StatelessWidget {
  const CustomButton({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

配置选项

json
{
    "generators": {
        "widget": {
            "path": "lib/widgets",
            "defaultType": "stateless", // 默认类型
            "fileSuffix": "" // 文件后缀(通常为空)
        }
    }
}

使用场景

  • 创建可复用的 UI 组件
  • 封装通用的界面元素
  • 提取重复的 UI 代码

Component(业务组件)

生成步骤

  1. 右键点击 widgetscomponents 文件夹
  2. 选择 Flu: 生成文件
  3. 选择 Component
  4. 输入组件名称(如 user_card

生成文件

lib/features/user/widgets/
└── user_card.dart

生成内容

dart
import 'package:flutter/material.dart';

class UserCard extends StatelessWidget {
  const UserCard({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Container(),
    );
  }
}

配置选项

json
{
    "generators": {
        "component": {
            "path": "lib/components",
            "defaultType": "stateless",
            "fileSuffix": ""
        }
    }
}

使用场景

  • 创建业务相关的组件
  • 封装特定功能的 UI
  • 模块内部使用的组件

Model(数据模型)

生成步骤

  1. 右键点击 models 文件夹
  2. 选择 Flu: 生成文件
  3. 选择 Model
  4. 输入模型名称(如 user

生成文件

lib/features/user/models/
└── user_model.dart

生成内容

dart
class UserModel {
  final String id;
  final String name;

  UserModel({
    required this.id,
    required this.name,
  });

  // 从 JSON 创建
  factory UserModel.fromJson(Map<String, dynamic> json) {
    return UserModel(
      id: json['id'] as String,
      name: json['name'] as String,
    );
  }

  // 转换为 JSON
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
    };
  }

  // 复制并修改
  UserModel copyWith({
    String? id,
    String? name,
  }) {
    return UserModel(
      id: id ?? this.id,
      name: name ?? this.name,
    );
  }
}

从 JSON 生成

如果你有 JSON 数据,可以自动生成模型:

  1. 创建 JSON 文件(如 user.json):

    json
    {
        "id": "1",
        "name": "John Doe",
        "email": "john@example.com",
        "age": 30,
        "is_active": true
    }
  2. 生成模型时选择 "从 JSON 生成"

  3. 选择 JSON 文件

  4. 扩展会自动推断类型并生成完整模型

配置选项

json
{
    "generators": {
        "model": {
            "path": "lib/models",
            "fileSuffix": "_model"
        }
    }
}

使用场景

  • 定义数据结构
  • API 响应模型
  • 本地数据模型

Service(服务类)

生成步骤

  1. 右键点击 services 文件夹
  2. 选择 Flu: 生成文件
  3. 选择 Service
  4. 输入服务名称(如 user
  5. 选择服务类型:
    • API Service:网络请求服务
    • Local Service:本地数据服务
    • Generic Service:通用服务

生成文件

lib/features/user/services/
└── user_service.dart

生成内容

API Service

dart
import 'package:http/http.dart' as http;
import 'dart:convert';

class UserService {
  final String baseUrl = 'https://api.example.com';

  // GET 请求
  Future<Map<String, dynamic>> getUser(String id) async {
    final response = await http.get(
      Uri.parse('$baseUrl/users/$id'),
    );

    if (response.statusCode == 200) {
      return json.decode(response.body);
    } else {
      throw Exception('Failed to load user');
    }
  }

  // POST 请求
  Future<Map<String, dynamic>> createUser(Map<String, dynamic> data) async {
    final response = await http.post(
      Uri.parse('$baseUrl/users'),
      headers: {'Content-Type': 'application/json'},
      body: json.encode(data),
    );

    if (response.statusCode == 201) {
      return json.decode(response.body);
    } else {
      throw Exception('Failed to create user');
    }
  }
}

配置选项

json
{
    "generators": {
        "service": {
            "path": "lib/services",
            "fileSuffix": "_service"
        }
    }
}

使用场景

  • 封装 API 请求
  • 本地数据库操作
  • 第三方服务集成

Module(模块)

生成步骤

  1. 右键点击 features 文件夹
  2. 选择 Flu: 生成文件
  3. 选择 Module
  4. 输入模块名称(如 user

生成结构

lib/features/user/
├── pages/
├── viewmodels/
├── widgets/
├── services/
├── models/
└── index.dart

index.dart 内容

dart
// Pages
export 'pages/user_page.dart';

// ViewModels
export 'viewmodels/user_viewmodel.dart';

// Widgets
export 'widgets/user_card.dart';

// Services
export 'services/user_service.dart';

// Models
export 'models/user_model.dart';

配置选项

json
{
    "generators": {
        "module": {
            "path": "lib/features/{feature}", // 支持 {feature} 占位符
            "structure": [
                "pages",
                "viewmodels",
                "widgets",
                "services",
                "models"
            ]
        }
    }
}

使用场景

  • 创建新的功能模块
  • 快速搭建模块结构
  • 保持项目结构一致

自动更新 index.dart

扩展会自动更新 index.dart 文件,添加新生成文件的导出:

更新规则

  1. 如果 index.dart 不存在,自动创建
  2. 如果已存在,自动添加新的导出
  3. 按类型分组(Pages、ViewModels、Widgets 等)
  4. 自动排序

示例

生成 user_page.dart 后,index.dart 会自动更新:

// Pages
export 'pages/home_page.dart';
export 'pages/user_page.dart';  // 新增

// ViewModels
export 'viewmodels/home_viewmodel.dart';
export 'viewmodels/user_viewmodel.dart';  // 新增

命名约定

扩展遵循以下命名约定:

文件命名

  • Page: {name}_page.dart
  • ViewModel: {name}_viewmodel.dart
  • Widget: {name}.dart
  • Component: {name}.dart
  • Model: {name}_model.dart
  • Service: {name}_service.dart

类命名

  • Page: {Name}Page
  • ViewModel: {Name}ViewModel
  • Widget: {Name}
  • Component: {Name}
  • Model: {Name}Model
  • Service: {Name}Service

示例

输入名称:user_list

生成文件:

  • user_list_page.dartUserListPage
  • user_list_viewmodel.dartUserListViewModel
  • user_list_model.dartUserListModel

常见问题

生成的文件路径不对?

检查 .flu-cli.json 配置文件中的 path 设置。

如何自定义生成内容?

使用 VSCode 代码片段自定义生成内容。详见 代码片段

可以批量生成吗?

目前不支持批量生成,但可以使用 Module 类型一次性创建完整结构。

生成后可以修改吗?

当然可以!生成的代码只是模板,你可以自由修改。

下一步

相关链接

Released under the MIT License.