前言
本文主要根据个人实践总结介绍Flutter项目结构和代码组织层面。
背景
初次开发Flutter项目,在Gitee上搜寻到Flutter Deer项目,经过分析和开发业务有一定契合度,借鉴了其项目结构和部分组件,前期确实起到事半功倍的效果。随着项目开发及需求升级,形成了多个业务APP(产品组),在组件应用、Model类、工具函数、API应用等方面出现大量冗余开发,对于项目维护及进一步开发造成巨大负担。
公共组件 + 工具函数
公共组件要应用于多个独立项目,需要以独立项目的形式提出去,以yaml方式引入。在业务项目同级构建一个packages目录用于存放基础依赖项目,包含自主开发的依赖项目和针对第三方包二次开发的依赖项目。
dependencies:
flutter:
sdk: flutter
# 1.引入第三方包,满足业务不做改造
flutter_screenutil: 5.5.3+2
# 2.自主开发的依赖项目
logistic_common:
path: ../packages/xxx-app-common
# 3.针对第三方包二次开发的依赖项目(原始包不能满足业务需求,本地二次开发后重新引入)
# 蓝牙打印
bluetooth_print:
path: ../packages/xxx-btprinter-plugin
再回到公共组件,其实公共组件也分为两类。
- 自主研发的公共组件
- 引入了第三方组件,需要再次封装的
除过类别外,组织形式也有很大差异,同时也进一步依赖常量、工具函数、子组件。
| 目录 | 功能 | 备注 |
|---|---|---|
| common | 公共业务组件 | 隐私检测、权限检测等(存在业务属性) |
| components | 基础组件 | 按钮、下拉框、表单等,构建项目基础风格的组件 |
| logger | 日志模块 | 引用日志组件,配置日志打印、存储。构建符合业务的日志管理体系 |
| provider | 组件的另一种应用方式 | 全局Loading的打开和释放 |
| res | 公共常量、枚举、样式 | |
| routes | 路由跳转、返回、拦截逻辑 | |
| utils | 工具函数 | 应用于公共组件及对外业务 |
| widgets | 公共组件 | 不存在业务属性 |
| app_config.dart | 注入配置的组件 | 构建业务基础架构 |
| logistic_common.dart | 定义仓库 | library logistic_common; |
Model类 + API应用
Model类和API定义要应用于多个独立项目,需要以独立项目的形式提出去,以yaml方式引入。
dependencies:
flutter:
sdk: flutter
flutter_screenutil: 5.5.3+2
# Model类 + API定义
logistic_api:
path: ../packages/xxx-app-api
xxx-app-api项目相对简洁很多,重点在Modal类的定义上,Modal类根据后端接口Modal做初步构建,根据界面逻辑适当补充模型参数。意味着Model类是后端 + 界面业务参数的合集,后端Model层级也得映射到Flutter Model中。
| 目录 | 功能 | 备注 |
|---|---|---|
| model | Modal类 | |
| request | API定义 | |
| logistic_api.dart | 定义仓库 | library logistic_api; |
业务层次
在业务开发中,引入基础依赖logistic_common、logistic_api,其它包按需引入。
dependencies:
flutter:
sdk: flutter
# 1.引入第三方包,满足业务不做改造
flutter_screenutil: 5.5.3+2
# 2.自主开发的依赖项目
logistic_common:
path: ../packages/xxx-app-common
# 3.针对第三方包二次开发的依赖项目(原始包不能满足业务需求,本地二次开发后重新引入)
# 蓝牙打印
bluetooth_print:
path: ../packages/xxx-btprinter-plugin
# Model类 + API定义
logistic_api:
path: ../packages/xxx-app-api
回到业务开发层级来介绍,经过封装单独library后,APP开发只聚焦到pages中的页面开发上,根据业务需求构建pages即可。
目录结构
| 目录 | 功能 | 备注 |
|---|---|---|
| pages | 业务页面 | |
| request | 按需实例化logistic_api中定义的接口类 | |
| routes | 业务定制化路由相关逻辑 | |
| utils | 业务相关的工具函数 | 多个APP相似使用场景可提到logistic_common |
| main.dart | 初始化业务项目 |
层次示例
界面目录构建
pages里面组织形式根据业务场景构建,路由配置根据界面划分集中构建。在logistic-common、logistic-api共用的情况下,业务APP-A上的模块可以以最小的代价快速迁移到业务APP-B,只需根据业务规划重新构建路由。
| 目录 | 功能 | 备注 |
|---|---|---|
| common | 放置当前业务的常量、枚举 | |
| page | 和路由对应的页面 | |
| provider | 业务状态管理(父子组件通讯) | |
| widget | 业务子组件 | |
| index.dart | 模块入口页面 |
后记
初识Flutter,从零到一,一路摸索前行。本文介绍多基于业务场景实践总结,希望对掘友有所帮助。