2022-04-11 00:03:27
Angular Composable 是一种在 Angular 项目中封装和重用有状态逻辑的设计模式,它借鉴了 Vue.js 的 Composables 概念,并结合 Angular 的 Signals API 和依赖注入系统实现。以下是详细解析:
核心概念有状态逻辑的封装
与 Lodash 等无状态工具库不同,Composables 通过函数封装可变状态(如用户输入、鼠标位置等)及其更新逻辑。
例如,useMouse() 函数封装了鼠标坐标的 Signal 状态和事件监听逻辑。
基于 Signals 的响应式能力
Angular 的 Signals(信号)是 Composables 的基础,提供细粒度的响应式更新。状态变化会自动触发组件重新渲染。
示例中 x 和 y 是信号,通过 x.update() 修改值时,依赖它们的组件会自动更新。
依赖注入与生命周期管理
使用 Angular 的 inject() 获取服务(如 DOCUMENT、DestroyRef),避免直接依赖全局对象。
通过 DestroyRef.onDestroy() 自动清理副作用(如移除事件监听),防止内存泄漏。
逻辑复用
将通用逻辑(如鼠标跟踪、表单验证)提取为独立函数,供多个组件共享,避免重复代码。
解耦与可测试性
组件只需调用 Composables 并消费其返回的状态,无需关心内部实现。逻辑更易于单独测试。
组合性
Composables 可以嵌套组合。例如,一个表单 Composable 可能组合多个字段验证逻辑。
逻辑与组件分离,可通过 mouse = useMouse() 在任意组件中复用。
自动管理事件监听的生命周期。
相似性:
均通过函数封装状态和逻辑,支持组合和复用。
使用响应式系统(Vue 的 ref/reactive vs Angular 的 Signals)。
差异:
Angular 依赖注入(如 inject(DOCUMENT))替代 Vue 的全局导入。
生命周期管理通过 DestroyRef 而非 Vue 的 onUnmounted 钩子。
跨组件共享状态
如用户偏好设置、主题切换等全局状态。
复杂交互逻辑
拖拽、滚动监听、键盘快捷键等需要副作用管理的场景。
表单处理
封装字段验证、提交状态等逻辑(类似 React 的 useForm)。
避免过度抽象
仅对真正复用的逻辑使用 Composables,简单逻辑可直接写在组件中。
性能优化
频繁更新的信号需注意计算开销,必要时使用 computed() 缓存派生值。
与现有模式的对比
服务(Services):适合无状态工具或全局共享服务(如 API 调用)。
指令(Directives):适合 DOM 操作(如自定义滚动行为)。
Composables:专注于组件内部的响应式状态逻辑。
Angular Composables 通过函数封装有状态逻辑,结合 Signals 和依赖注入,实现了逻辑复用与解耦。它填补了 Angular 在复杂状态管理上的灵活性空白,尤其适合需要组合多个响应式逻辑的场景。随着 Angular 生态对 Signals 的进一步支持(如基于信号的查询),Composables 的潜力将进一步释放。