11 KiB
常见 App 项目结构
Flutter 项目里,真正主要写代码的是 lib/。一个常见、可维护的 App 结构通常不是按“页面类型”乱放,而是按“应用层级 + 功能模块”来组织。
推荐结构大概是这样:
lib/
main.dart
app/
app.dart
router.dart
theme.dart
core/
config/
constants/
network/
storage/
errors/
utils/
features/
auth/
data/
domain/
presentation/
home/
data/
domain/
presentation/
profile/
data/
domain/
presentation/
shared/
widgets/
models/
extensions/
generated/
这是一种比较适合中大型 App 的结构。小项目可以简化。
main.dart
应用入口。
通常只做很少的事情:
void main() {
runApp(const App());
}
如果项目复杂一点,可能还会做:
- 初始化 Flutter 绑定
- 初始化本地存储
- 初始化日志
- 初始化 Firebase
- 初始化依赖注入
- 捕获全局异常
例如:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const App());
}
原则是:main.dart 不应该写页面 UI,也不应该堆业务逻辑。
app/
放整个 App 级别的配置。
常见内容:
app/
app.dart
router.dart
theme.dart
app.dart
放根组件,一般是 MaterialApp 或 MaterialApp.router。
例如:
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Patbond',
theme: AppTheme.light,
home: const HomePage(),
);
}
}
router.dart
放路由配置。
如果页面少,可以先不用这个文件。
如果后面页面多,建议用 go_router,比如:
/login
/home
/profile
/settings
theme.dart
放主题配置,例如:
- 主色
- 字体
- 按钮样式
- AppBar 样式
- 输入框样式
- 明暗主题
core/
放“全局基础能力”。
这些东西通常不属于某个具体页面或业务模块,而是整个 App 都可能用。
常见结构:
core/
config/
constants/
network/
storage/
errors/
utils/
core/config/
放环境配置,例如:
dev
test
prod
比如:
class AppConfig {
static const apiBaseUrl = 'https://api.example.com';
}
core/constants/
放全局常量,例如:
class AppConstants {
static const appName = 'Patbond';
}
可以包括:
- App 名称
- 默认分页大小
- 缓存 key
- 接口超时时间
- 正则表达式
core/network/
放网络请求相关代码,例如:
network/
api_client.dart
api_response.dart
interceptors.dart
如果用 dio,通常会在这里封装:
- baseUrl
- 请求头
- token
- 错误处理
- 超时
- 日志拦截器
core/storage/
放本地存储封装,例如:
- SharedPreferences
- SecureStorage
- Hive
- SQLite
比如:
storage/
local_storage.dart
secure_storage.dart
core/errors/
放错误类型和异常处理。
例如:
errors/
app_exception.dart
failure.dart
core/utils/
放通用工具方法。
例如:
- 日期格式化
- 金额格式化
- 防抖
- 校验函数
- 文件大小转换
注意:不要把业务逻辑都塞进 utils/,否则它会变成垃圾桶目录。
features/
这是业务模块目录,也是实际开发最常动的地方。
一个功能一个文件夹,比如:
features/
auth/
home/
profile/
order/
settings/
例如登录注册相关都放在:
features/auth/
首页相关放在:
features/home/
个人资料放在:
features/profile/
Feature 内部结构
中大型项目里,一个 feature 常见会分成三层:
features/auth/
data/
domain/
presentation/
这套结构接近 Clean Architecture,但不一定要一开始就完整照搬。
data/
负责数据来源。
常见内容:
data/
models/
repositories/
services/
例如:
features/auth/data/
models/
user_model.dart
login_request.dart
services/
auth_api_service.dart
repositories/
auth_repository_impl.dart
这里一般处理:
- API 请求
- JSON 解析
- 本地缓存
- 数据模型转换
例如 UserModel.fromJson() 通常就在 data/models/。
domain/
负责业务规则。
常见内容:
domain/
entities/
repositories/
usecases/
例如:
features/auth/domain/
entities/
user.dart
repositories/
auth_repository.dart
usecases/
login.dart
logout.dart
domain 理论上不关心数据来自哪里。
它只关心业务是什么。
例如:
abstract class AuthRepository {
Future<User> login(String email, String password);
}
然后 data 层去实现它。
小项目可以先不拆 domain/,直接用 data + presentation 就够了。
presentation/
负责 UI 和页面状态。
常见内容:
presentation/
pages/
widgets/
controllers/
例如:
features/auth/presentation/
pages/
login_page.dart
register_page.dart
widgets/
login_form.dart
controllers/
login_controller.dart
这里一般放:
- 页面
- 组件
- ViewModel / Controller / Bloc / Provider
- 页面状态类
如果用 Riverpod,可能是:
login_controller.dart
auth_provider.dart
如果用 Bloc,可能是:
auth_bloc.dart
auth_event.dart
auth_state.dart
shared/
放跨模块复用的 UI 或类型。
常见结构:
shared/
widgets/
models/
extensions/
shared/widgets/
通用组件,例如:
primary_button.dart
empty_view.dart
loading_view.dart
app_text_field.dart
network_image_view.dart
这些组件不属于某个具体业务模块,多个页面都能用。
shared/models/
通用模型,例如:
pagination.dart
option_item.dart
result.dart
shared/extensions/
Dart 扩展方法,例如:
extension StringX on String {
bool get isBlank => trim().isEmpty;
}
generated/
放自动生成代码。
例如:
- 国际化生成文件
- 路由生成文件
- JSON 序列化生成文件
- Assets 生成文件
这个目录通常不要手写业务逻辑。
资源目录
Flutter 资源通常不放在 lib/ 里,而是放在项目根目录。
常见结构:
assets/
images/
icons/
fonts/
lottie/
然后在 pubspec.yaml 注册:
flutter:
assets:
- assets/images/
- assets/icons/
- assets/lottie/
fonts:
- family: Inter
fonts:
- asset: assets/fonts/Inter-Regular.ttf
- asset: assets/fonts/Inter-Bold.ttf
weight: 700
测试目录
常见测试结构:
test/
features/
auth/
login_controller_test.dart
core/
network/
api_client_test.dart
测试可以按 lib/ 的结构对应放。
例如:
lib/features/auth/presentation/controllers/login_controller.dart
对应测试:
test/features/auth/presentation/controllers/login_controller_test.dart
小项目推荐结构
如果项目刚开始,不建议一上来就搞得太复杂。
当前项目可以先用这个结构:
lib/
main.dart
app/
app.dart
theme.dart
features/
home/
home_page.dart
shared/
widgets/
这就够了。
等有登录、接口、缓存、状态管理之后,再扩展成:
lib/
main.dart
app/
app.dart
router.dart
theme.dart
core/
network/
storage/
constants/
utils/
features/
auth/
data/
presentation/
home/
presentation/
profile/
data/
presentation/
shared/
widgets/
extensions/
不建议一开始这样做
不建议刚开始就建一堆空目录:
core/
errors/
failures/
usecases/
validators/
services/
managers/
helpers/
providers/
mixins/
这样看起来很专业,但实际开发时容易变成:
- 不知道代码该放哪
- 文件很多但内容很少
- 过度抽象
- 后期维护成本高
最好的做法是:随着需求出现再拆。
常见页面模块示例
假设要做一个带登录、首页、个人中心的 App,可以这样组织:
lib/
main.dart
app/
app.dart
router.dart
theme.dart
core/
network/
api_client.dart
storage/
token_storage.dart
constants/
app_constants.dart
features/
auth/
data/
auth_api.dart
auth_repository.dart
presentation/
login_page.dart
register_page.dart
auth_controller.dart
home/
presentation/
home_page.dart
home_controller.dart
widgets/
home_card.dart
profile/
data/
profile_api.dart
profile_repository.dart
presentation/
profile_page.dart
edit_profile_page.dart
shared/
widgets/
primary_button.dart
app_text_field.dart
loading_view.dart
empty_view.dart
常见开发流程
一般做 App 时,顺序可以是:
- 搭好
main.dart和app/app.dart - 建立主题
app/theme.dart - 创建首页
features/home/home_page.dart - 如果有多页面,再加
app/router.dart - 如果有接口,再加
core/network/ - 如果有登录 token,再加
core/storage/ - 每做一个功能,就在
features/下新建一个模块 - 多个模块共用的组件,再提到
shared/widgets/
放代码时的判断标准
页面放哪里:
features/模块名/presentation/
例如登录页:
features/auth/presentation/login_page.dart
接口请求放哪里:
features/模块名/data/
例如登录接口:
features/auth/data/auth_api.dart
多个模块共用的网络封装放哪里:
core/network/
例如:
core/network/api_client.dart
多个页面共用的按钮放哪里:
shared/widgets/
例如:
shared/widgets/primary_button.dart
App 主题放哪里:
app/theme.dart
路由放哪里:
app/router.dart
常量放哪里:
core/constants/
图片放哪里:
assets/images/
对当前项目的建议
现在最适合从这个结构开始:
lib/
main.dart
app/
app.dart
theme.dart
features/
home/
home_page.dart
shared/
widgets/
等开始做真实功能,比如登录、个人中心、业务列表,再扩展成:
features/
auth/
profile/
bond/
settings/
如果只是练手或做 MVP,不要过早引入完整 Clean Architecture。先保持简单,把页面跑起来、流程走通,再根据复杂度拆分。