10 KiB
10 KiB
name, overview, design, todos
| name | overview | design | todos | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| message-notification-components | 在 fms-vue 组件库新增 Message(轻提示)与 Notification(通知)两套组件,提供命令式全局 API(Message.success/error/...、Notification.open/close/closeAll)并保留可声明式使用的组件,遵循现有组件库规范(scoped SCSS + index.scss 变量、lucide 图标、Teleport/Transition 复用),最后在 App.vue 加演示入口并用 Playwright(端口 5082)实测。 |
|
|
用户需求
在 fms-vue 组件库中新增 Message(轻提示)与 Notification(通知)两套组件,采用命令式 API 为主、声明式组件为辅的设计。
产品概述
- Message:页面顶部居中的轻量级反馈提示,用于操作结果反馈,自动消失,不打断用户操作。
- Notification:页面右上角的通知卡片,用于承载较丰富的信息(标题 + 描述),支持手动关闭与自动消失。
- 两者均支持全局命令式调用(Message.success / Notification.open),同时保留
<Message>/<Notification>组件供声明式使用。
核心功能
- 命令式入口:Message.success/error/warning/info(content, options);Notification.open(options);均返回可关闭的实例句柄。
- 消息类型:info / success / warning / error 四种,复用 lucide 图标与现有主题 CSS 变量配色。
- 自动关闭:Message 默认 3000ms,Notification 默认 4500ms;duration 为 0 时不自动关闭。
- 手动关闭:Notification 提供关闭按钮;Message 在 hover 时可常驻并提供关闭按钮(可选)。
- 堆叠与重排:多条消息纵向堆叠(Message 顶部居中、Notification 右上角),关闭后后续项平滑上移。
- App.vue 演示区块:提供按钮触发各类型,便于人工与 Playwright 验证。
- 严格遵循现有项目规范(scoped SCSS + @use 模式、无 placeholder 逻辑、复用 Teleport/Transition 模式)。
技术栈选择
- 框架:Vue 3(SFC +
<script setup>),与现有组件一致 - 样式:SCSS(
scoped+@use './index.scss'),复用现有 CSS 变量与主题体系 - 图标:
@lucide/vue(已引入),复用 CheckCircle2 / AlertCircle / Info / X 等 - 浮层挂载:
Teleport to="body"+Transition,参考 Popover 模式但采用fixed固定定位(不跟随触发器)
实现方案
总体策略
采用「单例容器 + 程序化挂载」的命令式方案:每个管理器(message-manager / notification-manager)在首次调用时创建一个挂在 document.body 的容器组件(用 createVNode + render),容器内部用响应式数组维护当前活跃条目,新增时 push、关闭时移除并播放退场动画后卸载。组件本身(message.vue / notification.vue)作为单条目渲染单元,既被管理器内部使用,也可被外部声明式引用。
关键技术决策
- 单例容器 vs 每次新建:单例避免重复创建 DOM 与监听器,降低开销;容器组件统一管理 Transition 与堆叠计算。
- fixed 定位而非 Popover 定位逻辑:Message/Notification 不依赖触发元素,使用 CSS
position: fixed+ 居中/右上角偏移即可,无需引入 position.js 计算,减少依赖与复杂度。 - id 句柄关闭:每条目生成唯一 id,命令式调用返回
{ close },Notification.close(id)/closeAll通过 id 过滤数组实现。 - 自动关闭计时器:在条目组件内用
setTimeout,onBeforeUnmount清理;duration<=0 不启用。Hover 暂停(Notification 可选)提升可用性。 - 堆叠重排:依赖 Vue
<TransitionGroup>的 move 过渡实现关闭后其余项平滑位移,避免手动计算 top。
性能与可靠性
- 单例容器,全局仅 1 个监听器集合;条目数量受控(可设 maxCount 限制,超出时移除最早项)。
- 计时器在卸载时清理,防止内存泄漏;
render(null)在容器无条目且长时间空闲时可销毁(可选,初版保留单例)。 - 命令式 API 与组件 props 共用同一套类型定义,保证一致性。
实现注意事项
- 严格沿用现有组件 SFC 结构:
<style scoped lang="scss"> @use './index.scss',不写内联 style。 - 配色复用现有 CSS 变量(如
--fms-text-secondary、主色变量),接入 ColorThemePicker 主题体系,不硬编码颜色。 - 不得引入任何 placeholder 相关逻辑(遵循近期规范清理结果)。
- 图标复用
@lucide/vue,不新增图标依赖。 - 过渡动画命名约定风格与
popovertransition 一致(如message-fade、notification-slide)。 - 容器设置
pointer-events: none,子项pointer-events: auto,避免遮挡页面交互。
架构设计
组件关系
graph TD
A[命令式 API] --> B[message-manager.js]
A --> C[notification-manager.js]
B --> D[MessageContainer 内部]
C --> E[NotificationContainer 内部]
D --> F[message.vue 单条]
E --> G[notification.vue 单条]
F --> H[(document.body 单例容器)]
G --> H
管理器负责创建/复用 body 上的单例容器,容器内用 TransitionGroup 渲染多个条目组件。
目录结构
src/components/ui/
├── message/
│ ├── message.vue # [NEW] 单条消息组件。props: type/content/duration/closable/onClose;渲染图标+文案+关闭按钮;内置自动关闭计时与淡出;可被声明式使用
│ ├── message-manager.js # [NEW] 命令式入口。单例容器 createVNode+render 挂 body;导出 success/error/warning/info/close;维护活跃列表与堆叠
│ └── index.scss # [NEW] 消息样式。fixed 顶部居中、pointer-events 处理、type 配色、message-fade 过渡
├── notification/
│ ├── notification.vue # [NEW] 单条通知组件。props: type/title/description/duration/closable/onClose;图标+标题+描述+关闭按钮;自动关闭+滑动退场
│ ├── notification-manager.js# [NEW] 命令式入口。open/close(id)/closeAll;右上角堆叠、TransitionGroup 重排
│ └── index.scss # [NEW] 通知样式。右侧卡片、阴影、type 配色、notification-slide 进场/退场
└── (导出) 若项目存在 barrel 文件则补充导出,否则 App.vue 直接按路径 import
src/App.vue # [MODIFY] 新增演示区块:按钮组触发各类型 Message/Notification,沿用现有演示布局风格
关键代码结构
管理器导出口(message-manager.js):
export const Message = {
success: (content, opts) => open({ type: 'success', content, ...opts }),
error: (content, opts) => open({ type: 'error', content, ...opts }),
warning: (content, opts) => open({ type: 'warning', content, ...opts }),
info: (content, opts) => open({ type: 'info', content, ...opts }),
close: (id) => remove(id),
}
通知管理器导出口(notification-manager.js):
export const Notification = {
open: (options) => open({ ...options }),
close: (id) => remove(id),
closeAll: () => clear(),
}
设计风格
沿用现有 fms-vue 组件库的简洁卡片风格,与 Button/Select 视觉体系保持一致。Message 为顶部居中的轻量胶囊/卡片提示,带左侧类型图标与柔和阴影;Notification 为右上角白色卡片,左侧类型色条+图标,标题加粗、描述次要色,右上角关闭按钮。整体采用现有主题 CSS 变量配色,支持明暗主题切换,过渡平滑(淡入下滑 / 滑出上移)。
页面区块(App.vue 演示)
- 顶部标题区块:说明 Message 与 Notification 演示区
- Message 触发区:四枚按钮(info/success/warning/error)触发对应轻提示
- Notification 触发区:按钮触发通知,并含「关闭全部」按钮
- 底部说明:调用方式代码示例(纯文本展示)
Agent Extensions
Skill
- playwright-cli
- Purpose: 在端口 5082 启动/复用 dev server 后,通过 Playwright 实测 Message/Notification 的显示、自动消失、手动关闭与多条堆叠顺序
- Expected outcome: 验证各类型元素出现、文案与 type class 正确、duration 后自动移除、关闭按钮可移除、连续触发堆叠顺序正确,输出断言结果
SubAgent
- code-explorer
- Purpose: 在生成计划前确认 src/components/ui 是否存在 barrel 导出文件及 App.vue 现有演示区块结构,避免路径与风格冲突
- Expected outcome: 明确导出方式与 App.vue 插入位置,保证新增演示与现有布局一致