生成文件
本指南详细介绍如何使用 Flu CLI VSCode 扩展生成各种类型的文件。
生成方式
扩展提供 2 种生成文件的方式:
方式 1:右键菜单(推荐)⭐
- 在资源管理器中,右键点击目标文件夹
- 选择
Flu: 生成文件(或Flu: Generate) - 选择要生成的文件类型
- 按照提示完成生成
优点:
- 所见即所得,直接在目标位置生成
- 无需手动输入路径
- 操作直观
方式 2:命令面板
- 打开命令面板(
Cmd+Shift+P/Ctrl+Shift+P) - 输入
Flu: Generate - 选择目标文件夹
- 选择文件类型
- 按照提示完成生成
支持的文件类型
扩展支持生成以下类型的文件:
| 类型 | 说明 | 生成文件 |
|---|---|---|
| Page | 页面文件 | Page + ViewModel |
| ViewModel | 视图模型 | ViewModel |
| Widget | 通用组件 | Widget |
| Component | 业务组件 | Component |
| Model | 数据模型 | Model |
| Service | 服务类 | Service |
| Module | 完整模块 | 完整目录结构 |
Page(页面)
生成步骤
- 右键点击
pages文件夹 - 选择
Flu: 生成文件 - 选择
Page - 输入页面名称(如
home) - 选择页面类型:
- 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(视图模型)
生成步骤
- 右键点击
viewmodels文件夹 - 选择
Flu: 生成文件 - 选择
ViewModel - 输入名称(如
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(通用组件)
生成步骤
- 右键点击
widgets文件夹 - 选择
Flu: 生成文件 - 选择
Widget - 输入组件名称(如
custom_button) - 选择组件类型:
- 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(业务组件)
生成步骤
- 右键点击
widgets或components文件夹 - 选择
Flu: 生成文件 - 选择
Component - 输入组件名称(如
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(数据模型)
生成步骤
- 右键点击
models文件夹 - 选择
Flu: 生成文件 - 选择
Model - 输入模型名称(如
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 数据,可以自动生成模型:
创建 JSON 文件(如
user.json):json{ "id": "1", "name": "John Doe", "email": "john@example.com", "age": 30, "is_active": true }生成模型时选择 "从 JSON 生成"
选择 JSON 文件
扩展会自动推断类型并生成完整模型
配置选项
json
{
"generators": {
"model": {
"path": "lib/models",
"fileSuffix": "_model"
}
}
}使用场景
- 定义数据结构
- API 响应模型
- 本地数据模型
Service(服务类)
生成步骤
- 右键点击
services文件夹 - 选择
Flu: 生成文件 - 选择
Service - 输入服务名称(如
user) - 选择服务类型:
- 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(模块)
生成步骤
- 右键点击
features文件夹 - 选择
Flu: 生成文件 - 选择
Module - 输入模块名称(如
user)
生成结构
lib/features/user/
├── pages/
├── viewmodels/
├── widgets/
├── services/
├── models/
└── index.dartindex.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 文件,添加新生成文件的导出:
更新规则
- 如果
index.dart不存在,自动创建 - 如果已存在,自动添加新的导出
- 按类型分组(Pages、ViewModels、Widgets 等)
- 自动排序
示例
生成 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.dart→UserListPageuser_list_viewmodel.dart→UserListViewModeluser_list_model.dart→UserListModel
常见问题
生成的文件路径不对?
检查 .flu-cli.json 配置文件中的 path 设置。
如何自定义生成内容?
使用 VSCode 代码片段自定义生成内容。详见 代码片段。
可以批量生成吗?
目前不支持批量生成,但可以使用 Module 类型一次性创建完整结构。
生成后可以修改吗?
当然可以!生成的代码只是模板,你可以自由修改。