mcpField
V
vue-build-feature

vue-build-feature

github.com/basmilius开发0108 次安装4 天前更新
代码仓库

关于 vue-build-feature

vue-build-feature 是一份与库无关的指南,讲解如何从数据访问、组合式函数到组件、视图和路由构建多文件 Vue 3 功能。它规定职责划分和自底向上的构建顺序,适用于跨文件开发而非单个组件编写。

主要功能

  1. 01分离数据、状态与展示
  2. 02通过组合式函数加载功能数据
  3. 03按依赖顺序构建各层
  4. 04组织功能目录与导出入口
  5. 05配置路由及通用逻辑

适用场景

  1. 01规划多文件 Vue 3 功能
  2. 02组织由 API 驱动的页面与组件
  3. 03添加含加载和错误状态的路由
  4. 04协调覆盖层路由间的共享状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/basmilius/skills --skill vue-build-feature

安装后在 Claude Code 中输入/vue-build-feature确认已加载。

详细介绍

Vue 功能构建

如何构建一个无法放进单个组件的 Vue 3 功能:包括页面及其背后的组件、组合式函数、数据访问和路由,以及它们如何跨文件协同工作。本指南不依赖特定库。关于如何构建每个独立的 .vue 文件,请参考 code-style 中的 Vue 参考;关于如何选择 UI 组件(如果项目使用 Flux),请参考 flux-ui;项目特定规则(状态库、权限、i18n 位置)请参阅仓库中的 CLAUDE.md / AGENTS.md。

1. 核心原则:视图负责编排,组件负责呈现

  • 视图(页面)是唯一的编排者: 它通过实例化功能组合式函数(第 5 节)来管理数据、状态和处理函数。状态存放在组合式函数中;视图是唯一通过 props / v-model 将状态与子组件连接起来的地方。子组件不会持有规范状态——它们会发出事件或写入 model 来请求更改。
  • 展示型组件只接收 props、发出事件: 只使用 defineProps、defineEmits、defineModel,不自行获取数据。
  • 拆分,不要堆在一起。 将每个包含大量标记的区块(工具栏、筛选器、卡片、列表、总计、空状态)拆成独立组件。

2. 一个功能的各个层次

一个较复杂的功能通常涉及以下层次。请保持分离:

层次内容
数据访问类型/模型,以及与 API 通信的服务/客户端
组合式函数获取数据、加载/错误状态,以及视图的派生状态
组件功能文件夹中的展示型组件,以及导出汇总文件
视图/页面编排者:管理状态、组合组件
路由路由器入口(延迟导入、守卫、meta)
横切关注点共享工具函数/格式化器、图标、面向用户的文本(i18n)

各层的存放位置因项目而异;保持层次分离则始终不变。不要在组件中获取数据——应通过数据层和组合式函数完成。

3. 构建顺序(自底向上)

从依赖最少的层开始向上构建,让每一层都能基于下一层编译:

  1. 数据访问——类型/模型 + 服务方法。
  2. 组合式函数——封装视图的加载和状态。
  3. 展示型组件——每个区块一个组件,并提供功能导出汇总文件。
  4. 视图——将组合式函数与组件连接起来。
  5. 路由——注册视图。
  6. 横切关注点——工具函数/格式化器、图标、i18n 键。

4. 目录结构与导出汇总文件

  • 将某个功能的组件归入同一个文件夹,例如 component/<domain>/<feature>/,并在其中放置用于共享结构的 types.ts,以及一个重新导出该文件夹内容的 index.ts 导出汇总文件。
  • 领域共享组件直接放在 component/<domain>/ 中, 与功能子文件夹并列,而不是放在 common/ 子目录中。将功能专属组件放在 component/<domain>/<feature>/ 子文件夹中,并将真正适用于整个应用的通用组件放在顶层的 component/common/ 中。
  • 通过组件自身的路径导入领域共享组件(@/component/<domain>/<Name>.vue),不要通过领域导出汇总文件导入:该汇总文件会重新导出导入它的功能,绕道导入会造成循环依赖。
  • 通过路径别名导入(@/component/...、@/composable 等),不要使用深层相对路径。同一功能中并列放置的子组件才使用相对导入。
  • 创建新文件后立即将其接入导出汇总文件, 让应用其他部分始终从同一个稳定入口导入。
component/
  common/                 app-generic components (AppIcon, layout, ...)
  <domain>/
    <Domain>Badge.vue     shared directly across the domain's features
    index.ts              barrel: shared pieces + the feature barrels
    <feature>/            one feature's presentational pieces
      types.ts            shapes shared within the feature
      index.ts            barrel: re-exports the folder

5. 在组合式函数中加载数据,而不是在视图中

  • 将 fetch、加载/错误处理和防抖/竞态保护放在 use<Feature> 组合式函数中;视图使用它({ data, isLoading, isEmpty, error, reload }),专注于组合内容,而不是处理底层逻辑。
  • 同时公开空状态和错误状态,而不只是加载状态。 推导出 isEmpty,确保它不会在 fetch 过程中闪现(loaded && !isLoading && count === 0),并按以下顺序渲染各种状态:加载时显示骨架屏,然后是错误状态、空状态,最后是数据。
  • 不要在视图中手动编写 watch + fetch + 防抖逻辑。优先使用项目现有的数据辅助工具(列表/表格或报告组合式函数,或数据获取库),并参照最接近的实现新建。如果没有现成实现(全新项目),编写一个小型的竞态保护基础工具(fetch + 加载状态 + 错误状态 + 一个用于丢弃过期响应的请求令牌),并让每个功能的组合式函数以此为基础。
  • **如果项目使用 @basmilius/common,**其 useDataTable / useDataReport 就是该数据辅助工具,并由 @basmilius/http-client 服务和 DTO 提供支持(两者详见 basmilius 技能)。

6. 重置共享状态/模块级状态

  • 如果组合式函数或 store 将列表保存在与子路由/覆盖层路由共享的模块级(单例)状态中,请为其提供 reset(),并在列表视图的 onUnmounted 中调用(或监听上下文键并在其变化时重置)。
  • 否则,重新访问页面时会先同步重新渲染过期、可能很庞大的状态,然后才重新加载;这可能导致 UI 卡顿,且没有加载指示器。
  • 组件作用域的组合式函数状态无需 reset()。 视图实例化的组合式函数中创建的状态会随视图一起销毁;只有模块级(单例)状态或生命周期超出视图的 store 状态才需要重置。
  • reset() 不得触发重新 fetch。 如果组合式函数会监听筛选条件并重新 fetch,那么在销毁期间于 reset() 中清空筛选条件会安排一次过期请求;应同时重置输入和缓存数据,不要再次触发 fetch。

7. 路由器和路由

  • 每个屏幕对应一条路由;使用动态 import() 延迟加载视图。
  • 将横切关注点放入路由 meta(守卫、权限、标题),并在导航守卫中读取,而不是在每个视图中进行检查。
  • 将模态/覆盖层屏幕建模为路由,以支持深层链接或返回操作。将覆盖层设为列表的子路由,这样列表会保持挂载在其下方(这也是只有离开此功能时才会触发其 reset() 的原因,见第 6 节),并通过嵌套的 <RouterView> 渲染。将路由参数作为 props 传入(props: true),而不是使用 useRoute();通过导航到父路由来关闭,不要调用 router.back(),这样即使从深层链接直接进入,也仍然可以退出。
  • 权限/守卫的具体实现因项目而异(请遵循仓库的 CLAUDE.md);模式是:在 meta 中声明,并在守卫中强制执行。

8. 横切关注点

  • 在项目的中央图标注册表中注册图标;图标名称值应使用项目的图标名称类型,而不是 string。
  • 将共享格式化函数放在 util/ 中(通过 barrel 导出),复用项目的工具库,而不是在模板中内联 Intl/格式化逻辑。
  • 用户可见文本应通过项目的 i18n 层处理,并为项目提供的每种语言环境设置对应键。

相关技能

  • code-style —— 如何构建此功能新增的每个 .vue 文件。
  • flux-ui —— 项目使用 Flux 时,如何选择和组合组件。
  • basmilius —— 如果项目使用 @basmilius/* 包(由 Bas Milius 开发),此技能将介绍项目特定的数据层(DTO 服务)和状态/组合式函数层(useDataTable、store)。
  • 仓库的 CLAUDE.md / AGENTS.md —— 状态/数据库、权限模型、i18n 位置及其他项目特定规则。

评论

支持 Markdown