从零搭建到长期维护:一套面向真实业务的 Flutter 基础框架
很多 Flutter 项目在启动阶段都会重复经历同一套流程:配置路由、封装 Dio、定义请求结果、编写页面基类,再补齐按钮、弹窗、输入框、主题和资源目录。
这些工作并不复杂,却会持续消耗时间。更重要的是,如果项目从一开始缺少统一边界,随着业务增长和人员协作,路由、网络请求、公共组件与业务代码很容易逐渐混在一起。
因此,一套有价值的 Flutter 基础框架,不应该只是几个 Demo 页面或简单脚手架,而应该是一份能够直接复制、快速启动,并支持长期维护的母版工程。
一、框架解决的核心问题
这套框架面向实际业务项目,重点沉淀以下通用能力:
-
应用启动与入口配置
-
页面基类与页面状态管理
-
路由统一管理
-
网络请求统一封装
-
H5 页面容器
-
通用组件和工具类
-
代码风格与目录职责约束
它更适合持续迭代的业务项目,而不是只用于展示效果的示例工程。其目标可以概括为四点:
-
减少新项目重复搭建基础设施的时间;
-
统一多人协作时的代码组织方式;
-
降低入口、路由和公共能力的修改成本;
-
避免项目扩大后框架层与业务层边界失控。
二、框架的核心优势
1. 复制模板即可进入业务开发
路由、网络层、页面基类、通用组件、开屏页和主题资源等能力已经提前整理。创建新项目时,可以直接复制模板,从配置层和业务层开始填充内容,而不必再次从零搭建基础结构。
2. 目录职责清晰,降低维护成本
框架提前明确了常见公共能力应该放在哪里:
-
路由由
router/统一管理; -
网络能力集中在
net/; -
页面基础抽象放在
base/; -
跨模块组件放在
widgets/; -
全局配置集中在
common/; -
业务页面统一进入
pages/。
清晰的边界可以让新成员更快理解项目,也能避免公共逻辑散落在各个业务页面中。
3. 启动入口集中配置
应用名称、项目标识、开屏页开关、开屏页路由和首页路由统一维护在:
lib/common/app_definition.dart
例如,项目是否启用开屏页、启动后进入哪个首页,都可以在统一位置调整,不必在多个文件中查找跳转逻辑。
4. 完整的页面基础抽象
框架保留了一组适合真实业务落地的页面基类:
-
BasePage -
BasePageState -
BasePageNormalState -
BaseListPageState -
BaseListNormalPageState -
PageConfig
这些抽象用于统一处理页面标题栏、返回逻辑、状态栏、通用布局,以及 loading、fail、normal 等页面状态。列表页面还可以在统一结构中实现刷新和加载更多,避免每个页面重复编写相似逻辑。
5. 标准化网络请求层
网络层使用统一请求封装与适配器模式,主要包括:
-
DioNet -
ApiBaseAdapter<T> -
DataResult -
ApiCode -
TokenInterceptor
页面不直接耦合裸 Dio,请求结果通过统一结构返回,不同接口则可以按适配器拆分。这种设计为后续加入 Token、公共请求头、错误处理和日志等能力预留了清晰的扩展位置。
6. 可复用的 H5 容器
框架内置通用 Web 容器页、路由入参结构,以及可选的 H5 预加载服务,可用于承载:
-
用户协议与隐私政策;
-
活动页和 Web 落地页;
-
后端动态下发页面;
-
其他轻量混合业务页面。
这样可以避免不同业务模块反复实现 WebView 容器。
三、整体目录结构
lib/
app.dart
main.dart
base/
common/
event/
net/
pages/
provider/
res/
router/
services/
utils/
widgets/
目录数量不是重点,重点是每一层都有明确职责。
main.dart:应用启动入口
负责启动 Flutter、执行最早期初始化,并运行根应用。该文件应尽量保持简洁,避免堆积业务逻辑。
app.dart:根应用配置
负责 Provider 注册、Theme 与 Router 挂载,以及全局 MaterialApp 的组织。
common/:全局配置与常量
当前重点包括:
-
app_definition.dart -
constant.dart
主要用于维护应用名称、启动入口、项目常量和通用 Key。
base/:页面基础抽象
提供页面壳子、页面状态切换、列表页基础能力和 MVP 结构壳子,是整个框架的核心层之一。
router/:统一路由层
集中维护路由常量、路由分发、全局导航入口和路由监听,避免页面之间通过零散字符串互相跳转。
net/:网络请求层
统一请求入口、返回结构、接口常量、拦截器和适配器模式。页面只关心请求参数和业务结果,不需要重复处理底层通信细节。
res/:资源规范层
集中维护主题、字号、间距和颜色规则。框架只定义颜色文件的组织方式和命名约定,不预设具体业务颜色,使模板能够适配不同项目的视觉体系。
widgets/:通用组件层
可放置按钮、输入框、弹窗、底部弹窗、空态、加载框、AppBar 和 WebContainer 等跨业务模块复用的组件,但不应承载某个业务模块的专属 UI。
provider/:共享状态层
用于承载会话状态、配置状态、本地设置状态和通用列表状态。框架保留状态管理的扩展壳子,但不绑定具体登录模型和业务字段。
services/:基础服务层
用于存放相对独立的基础服务,例如 WebView 预加载能力。
utils/:轻量工具层
用于维护权限、Toast、正则和通用辅助函数。工具类应保持职责单一,避免最终演变成无边界的“大杂烩”。
pages/:业务页面层
模板只保留必要的占位入口页,不塞入大量业务页面。原因很简单:这是一套基础模板,提供的是稳定的工程壳子,而不是特定业务内容。
四、开屏页与首页入口设计
启动入口往往是新项目中改动最频繁的部分。有的项目需要开屏页,有的直接进入首页,还有的需要先判断登录状态或展示引导页。
为避免入口逻辑散落,框架通过 lib/common/app_definition.dart 集中维护:
-
AppIdentity.appName -
AppLaunchConfig.enableSplashPage -
AppLaunchConfig.splashPageRoute -
AppLaunchConfig.homePageRoute
框架还提供默认占位开屏页:
lib/pages/splash/default_splash_page.dart
它并非正式业务开屏页,而是用于保证模板的启动链路完整,同时向接手者展示开屏页的替换方式。复制模板后,即使尚未编写业务页面,也能够获得完整、清晰的启动流程。
五、规范比目录本身更重要
基础框架不仅要提供文件,还要提供稳定的扩展方式。因此,项目通过 CODE_STYLE_GUIDE.md 约定代码风格与目录边界。
基础文件需要说明用途
每个基础文件都应说明它负责什么、应该如何使用。模板未来可能由不同成员维护,清晰注释可以显著降低理解成本。
目录之间必须有边界
并不是所有公共代码都应该进入 utils/,也不是所有 UI 代码都适合放进 widgets/。只有先明确职责,团队才能长期维持一致的项目结构。
公共层保持去业务化
框架层应尽量避免绑定:
-
特定用户或商品模型;
-
某个业务接口路径;
-
某个项目专属流程;
-
具体品牌的颜色与视觉规则。
只有保持通用,基础模板才具备跨项目复制的价值。
扩展时优先使用已有抽象
例如:
-
普通页面优先复用
BasePageNormalState; -
列表页面优先复用
BaseListNormalPageState; -
接口适配优先复用
ApiBaseAdapter<T>。
这能避免项目中出现多套功能相似、结构不同的平行实现。
六、适用场景
中小型、持续迭代的业务团队
当项目需要长期维护、人员可能发生轮换时,统一的页面、网络和目录规范可以降低交接成本。
经常创建多个项目的团队
如果团队频繁启动相似业务,不必每次重新配置基础设施。复制母版后,修改入口和项目配置即可进入业务开发。
有 Flutter 与 H5 混合需求的项目
对于经常承载协议、活动页、落地页或动态 Web 内容的应用,统一 WebContainer 和预加载能力会更实用。
重视长期维护的项目
如果目标不是完成短期 Demo,而是让项目能够持续扩展并被其他开发者接手,那么规范化基础框架通常比轻量脚手架更有价值。
七、边界与设计取舍
为了保证通用性,这套模板做了三项明确取舍。
不内置大量业务页面
业务页面越多,模板越重,也越容易携带特定项目的设计假设。模板只提供页面结构和必要占位入口。
不预定义业务颜色
不同项目的品牌和视觉风格差异很大,因此框架只保留集中式颜色文件、注释分区与命名规则,实际色值由具体项目定义。
不绑定具体登录模型
登录字段和流程通常存在较大差异。框架只保留会话、配置和本地设置等状态管理壳子,不预设具体业务模型。
八、后续演进方向
在保持“只扩展通用层、不侵入业务层”的前提下,框架还可以从以下方向继续完善。
1. 补充项目初始化指南
整理项目名、包名、应用显示名、开屏页、首页、主题和接口地址的修改步骤,让新成员能够更快完成初始化。
2. 提供脚本化改名能力
可以进一步实现项目名、包名和显示名的一键替换,减少复制模板后的机械操作。
3. 丰富通用基础组件
后续可以按真实项目需求逐步加入:
-
通用 Tab 容器;
-
通用筛选栏;
-
通用分页请求工具;
-
通用表单校验规则。
新增能力仍需遵循同一个原则:只沉淀跨项目可复用的基础设施,不把具体业务带入模板。
九、总结
一套 Flutter 基础框架的价值,不在于目录多、文件多,而在于它是否提前整理了真实业务中最容易重复、最容易混乱,也最值得统一的部分。
这套模板通过集中入口配置、页面状态抽象、统一路由、标准化网络层、H5 容器、通用组件和代码规范,提供了一份可直接复制并持续扩展的工程母版。
如果希望 Flutter 项目从第一天开始就拥有清晰边界,并在多人协作与长期迭代中保持稳定,那么先建立统一的基础框架,往往比直接从空工程堆叠业务代码更值得投入。

评论
0 条讨论