feat: 提交多个新UI组件模块spec和相关属性设定,包括卡片封装、渐变卡片、列式布局组件等,重写了readme.md,用于AI Coding
Some checks are pending
Call HTTPS API / build (push) Waiting to run

This commit is contained in:
2025-12-27 15:42:57 +08:00
parent fc9c726de4
commit 55abf26cfa
78 changed files with 3024 additions and 103 deletions

View File

@@ -0,0 +1,27 @@
# Module Specaccess-controlACL + hasPermission + v-permissions
module:
id: access-control
name: 访问控制(角色/权限/指令)
type: core
entrypoints:
- src/store/modules/acl.ts
- src/utils/permission.ts
- library/plugins/directive.ts
public_api:
concept:
- "useAclStore 保存 admin/role/permission"
- "hasPermission(target) 统一判断路由/按钮权限"
- "v-permissions 指令在模板侧消费 hasPermission"
dependency_closure:
runtime:
- "Pinia store 初始化src/store/index.ts"
acceptance:
- "acl 中 admin=true 时 hasPermission 永远为 true"
- "指令 v-permissions 可用且不报错(具体隐藏/移除行为以实现为准)"
pitfalls:
- "权限数据来源通常由 user.getUserInfo() 写入 acl抽取时需明确数据流"

View File

@@ -0,0 +1,34 @@
# Module Specapi-systemsrc/api + axios request 封装)
module:
id: api-system
name: API 层src/api 域拆分 + src/utils/request.ts
type: core
entrypoints:
- src/api/
- src/utils/request.ts
public_api:
concept:
- "src/api/<domain>.ts按业务域拆分 API 函数"
- "src/utils/request.tsaxios 实例 + 拦截器 + 统一错误处理 + token 注入"
dependency_closure:
runtime:
- "axiosinstance + interceptors"
- "qsx-www-form-urlencoded 序列化)"
- "store/usertoken 注入、401/402 时 resetAll / refresh token"
- "plugin-vabgp.$baseMessage / gp.$baseLoadingloading 与错误提示)"
- "plugin-errorlogneedErrorLog/addErrorLog请求异常入库"
- "router401/403 跳转"
- "configbaseURL/requestTimeout/contentType/successCode/statusName/messageName/debounce 等"
- "api/refreshToken402 刷新 token 重试队列"
acceptance:
- "正常接口返回 code=200 时返回 data"
- "401 跳转 /login 且 resetAll 执行"
- "402 触发 refreshToken 并重放队列请求"
pitfalls:
- "request.ts 强依赖 gp全局注入与 user store抽取到新项目需明确入口安装顺序"
- "successCode/statusName/messageName 等与后端协议强耦合,迁移时先在规格声明差异"

View File

@@ -0,0 +1,31 @@
# Module Specconfig-systemsrc/config配置聚合
module:
id: config-system
name: 配置系统src/config 聚合导出)
type: core
entrypoints:
- src/config/index.js
- src/config/cli.config.js
- src/config/setting.config.js
- src/config/theme.config.js
- src/config/net.config.js
public_api:
concept:
- "src/config/index.js 将 4 个子配置聚合导出cli/setting/theme/network"
- "部分配置会被 vue.config.js 以 Node 方式 require 读取,因此子配置文件应保持 Node 兼容(避免 window/document"
key_index:
- "authentication/loginInterception/routesWhiteList/supportVisit/rolesControl/isHashRouterMode"
- "tokenName/tokenTableName/storage/recordRoute"
- "title/titleSeparator/titleReverse"
- "defaultOpeneds/uniqueOpened/openFirstMenu"
- "layout/themeName/menuWidth/columnStyle/showProgressBar/showTabs/showTheme/showThemeSetting"
- "baseURL/contentType/requestTimeout/successCode/statusName/messageName"
acceptance:
- "运行构建/启动时vue.config.js require config 不报错"
pitfalls:
- "配置文件在 Node 侧执行:避免使用浏览器对象"

View File

@@ -0,0 +1,20 @@
# Module Speciconssrc/iconSVG 自动加载)
module:
id: icons
name: SVG Iconssrc/icon require.context 自动加载)
type: ui
entrypoints:
- src/icon/index.ts
- src/icon/*.svg
public_api:
concept:
- "通过 require.context 自动加载 src/icon 下的 svg构建期打包进 sprite/资源管线,取决于 webpack 配置)"
dependency_closure:
bundler:
- "webpack require.context"
acceptance:
- "启动后 svg 资源被打包且可引用(具体引用方式取决于项目现有 svg loader 配置)"

View File

@@ -0,0 +1,40 @@
# Module Speclayouts布局体系
module:
id: layouts
name: 布局体系Layout Shell + 多布局实现)
type: ui
entrypoints:
- library/layouts/index.vue
- library/layouts/VabLayoutVertical/
- library/layouts/VabLayoutHorizontal/
- library/layouts/VabLayoutCommon/
- library/layouts/VabLayoutComprehensive/
- library/layouts/VabLayoutFloat/
- library/layouts/VabLayoutColumn/
public_api:
concept:
- "通过 theme.layout 选择渲染的布局组件:<component :is=\"'vab-layout-' + theme.layout\" />"
usage_examples:
- "在 settings store 中设置 theme.layout 为 vertical/horizontal/...Layout 会动态切换"
dependency_closure:
runtime:
- "Pinia settings storesrc/store/modules/settingstheme/layout/collapse/device"
- "Element Plusel-backtop"
- "Theme 组件library/components/VabThemeVabThemeDrawer/VabThemeSetting"
- "事件总线注入library/plugins/vab.ts$pub/$sub/$unsubTheme 抽屉依赖该注入)"
styles:
- "library/styles/variables/variables.module.scss布局 SCSS 变量)"
- "library/styles/variables/vab-*-variables.module.scssTheme 注入 Element Plus CSS 变量)"
acceptance:
- "Layout 可渲染并不报错"
- "窗口宽度 < 992 时进入 mobile 模式并能折叠菜单watch/resize 生效)"
- "Theme 抽屉/设置入口存在时不报错(缺失 $pub/$sub 注入会导致 Theme 不工作)"
pitfalls:
- "Layout 通过 require.context 自动注册 layouts 子目录下的 .vue迁移到非 webpack 环境时需要等效能力或手动注册"
- "Layout 与 Theme 都依赖 webpack 能力require.context / 动态 require scss module抽取到非 webpack 构建器时需要等效替代方案"

View File

@@ -0,0 +1,21 @@
# Module Spec示例mock
module:
id: mock
name: 本地 MockdevServer 中间件)
entrypoints:
- mock/index.js
- mock/controller
public_api:
concept:
- "route object: { url, type, response }"
usage_examples:
- "在 mock/controller/<domain>.js 增加路由对象devServer 会自动注册"
acceptance:
- "启动开发服务器后,请求命中 mock 并返回 mockjs 数据"
pitfalls:
- "路由匹配会自动拼 baseURL 前缀(来自 src/config"

View File

@@ -0,0 +1,19 @@
# Module Specplop代码生成器
module:
id: plop
name: Plop 代码生成器view/curd/component/mock&api
type: tooling
entrypoints:
- plopfile.js
- plop-templates/
public_api:
concept:
- "通过 plop generators 生成页面、curd、组件以及 mock&api 框架代码"
acceptance:
- "执行 plop 命令可正常出现 generators 并生成文件"
pitfalls:
- "生成结果依赖仓库既有目录约定src/views、src/api、mock/controller 等);新项目需对齐目录或改模板"

View File

@@ -0,0 +1,24 @@
# Module Specplugin-directive自定义指令v-permissions
module:
id: plugin-directive
name: 自定义指令v-permissions 权限控制)
type: plugin
entrypoints:
- library/plugins/directive.ts
public_api:
concept:
- "注册 v-permissions 指令,用于按权限隐藏/禁用 UI"
dependency_closure:
runtime:
- "权限判断src/utils/permissionhasPermission"
- "路由/用户权限数据:通常来自 store/user 或 routes 权限模块(视实现而定)"
acceptance:
- "模板中存在 v-permissions 使用时不报错"
- "无权限时能按设计移除/隐藏元素(以 hasPermission 实现为准)"
pitfalls:
- "指令依赖 hasPermission 的语义;抽取到目标项目需同步其实现与权限数据来源"

View File

@@ -0,0 +1,24 @@
# Module Specplugin-errorlog全局错误捕获与上报 store
module:
id: plugin-errorlog
name: 错误日志插件app.config.errorHandler + store 收集)
type: plugin
entrypoints:
- library/plugins/errorLog.ts
public_api:
concept:
- "根据配置决定是否启用全局 errorHandler"
- "将错误写入 useErrorLogStore用于页面展示/上报)"
dependency_closure:
runtime:
- "Piniasrc/store/modules/errorLoguseErrorLogStore"
- "configsrc/config/errorLog或 src/config/index.js 聚合)"
acceptance:
- "启用后,运行时异常会进入 error log store"
pitfalls:
- "若 store 未初始化或模块缺失,会导致 errorHandler 内再次报错"

View File

@@ -0,0 +1,23 @@
# Module Specplugin-support生产环境信息/依赖检查)
module:
id: plugin-support
name: Support 插件(构建信息输出/依赖检查)
type: plugin
entrypoints:
- library/plugins/support.ts
public_api:
concept:
- "生产环境输出构建信息__APP_INFO__"
- "检查关键依赖是否存在(例如 vab-icons"
dependency_closure:
runtime:
- "__APP_INFO__ 全局常量(通常由构建注入)"
acceptance:
- "生产环境能按预期打印/校验,不影响运行"
pitfalls:
- "依赖检查失败可能影响全局能力(与 vab 插件的保护逻辑相关)"

View File

@@ -0,0 +1,29 @@
# Module Specplugin-vab全局能力注入 + 事件总线)
module:
id: plugin-vab
name: Vab 插件gp 全局方法 + mitt 事件总线)
type: plugin
entrypoints:
- library/plugins/vab.ts
public_api:
concept:
- "通过 app.provide + app.config.globalProperties 注入 gp$baseLoading/$baseMessage/$baseAlert/$baseConfirm/$baseNotify/$baseTableHeight/$pub/$sub/$unsub"
- "内部使用 mitt 作为事件总线实现 $pub/$sub/$unsub"
dependency_closure:
runtime:
- "Element PlusElLoading / ElMessage / ElMessageBox / ElNotification"
- "mitt"
- "lodash"
- "src/configloadingText/messageDuration"
types:
- "types/library.d.tsglobalPropertiesType"
acceptance:
- "安装插件后,可通过 inject('$pub')/this.$pub 发布事件"
- "$baseMessage/$baseLoading 能正常工作"
pitfalls:
- "生产环境存在授权/依赖检查逻辑,可能将 app.config.globalProperties 置空(不要在外部假设 gp 永远存在)"

View File

@@ -0,0 +1,37 @@
# Module Specrouter路由与权限守卫
module:
id: router
name: 路由与页面组织
entrypoints:
- src/router/index.ts
- src/router/permissions.ts
public_api:
exports:
- constantRoutes
- asyncRoutes
- setupPermissions(router)
usage_examples:
- "新增页面:在 src/views/<module>/ 添加 Vue 文件,并在 asyncRoutes 中挂载到 Layout children"
dependency_closure:
runtime:
- "routervue-routerbeforeEach/afterEach"
- "store-usertoken/getUserInfo/resetAll/setVirtualRoles"
- "store-routessetRoutes(authentication)"
- "store-settingstheme.showProgressBar"
- "configauthentication/loginInterception/routesWhiteList/supportVisit"
- "utils/pageTitlegetPageTitle(to.meta.title)"
- "utils/routestoLoginRoute"
- "nprogressVabProgress含 nprogress.css"
acceptance:
- "路由可跳转"
- "刷新后路由仍可恢复"
pitfalls:
- "如涉及权限/菜单,需同步 metatitle/icon/...);同时注意 routesWhiteList/loginInterception/authentication 等开关影响守卫逻辑"
- "permissions.ts 直接写 document.title若新项目改为 useHead 等方式需统一"

View File

@@ -0,0 +1,30 @@
# Module Specsetup-vablibrary/index.ts自动加载、图标、样式、插件
module:
id: setup-vab
name: setupVab(app)(自动加载 styles/background/plugins + 图标注册)
type: core
entrypoints:
- library/index.ts
public_api:
concept:
- "setupVab(app) 是本模板把 'library/' 能力接入应用的总入口"
- "它负责:加载 svg 图标、全局样式、注册图标组件、自动加载背景样式与 plugins"
dependency_closure:
runtime:
- "src/icon/index.tssvg require.context"
- "library/styles/vab.scss全局样式入口"
- "@vueuse/headcreateHead"
- "vab-iconsVabIcon 组件 + CSS"
- "@element-plus/icons-vue全量注册 ElementPlus 图标组件)"
bundler:
- "webpack require.contextbackground scss / plugins ts 自动加载"
acceptance:
- "调用 setupVab(app) 后VabIcon 可用、ElementPlus 图标组件可用"
- "plugins 自动 app.use 安装,$pub/$sub 等全局注入可用(由 plugin-vab 决定)"
pitfalls:
- "setupVab 依赖 require.context迁移到非 webpack 构建器需要替代实现(手动 import 或 glob"

View File

@@ -0,0 +1,23 @@
# Module Specstore-errorlog错误日志收集 store
module:
id: store-errorlog
name: ErrorLog Store错误日志收集
type: store
entrypoints:
- src/store/modules/errorLog.ts
public_api:
concept:
- "addErrorLog追加错误日志"
- "clearErrorLog清空错误日志"
dependency_closure:
runtime:
- "通常由 plugin-errorloglibrary/plugins/errorLog.ts与 request 异常写入触发"
acceptance:
- "触发 addErrorLog 后 errorLogs 可读取"
pitfalls:
- "若错误处理链路缺失plugin/request 未接入store 仍可用但不会自动产生数据"

View File

@@ -0,0 +1,28 @@
# Module Specstore-routes路由模式/菜单路由状态)
module:
id: store-routes
name: Routes Store路由拦截/菜单路由设置)
type: store
entrypoints:
- src/store/modules/routes.ts
public_api:
concept:
- "setRoutes(mode):根据 authentication/rolesControl 生成可访问路由并 resetRouter"
- "支持前端路由asyncRoutes与后端路由getList -> convertRouter两种模式"
dependency_closure:
runtime:
- "routersrc/routerasyncRoutes/constantRoutes/resetRouter"
- "utils/routesconvertRouter/filterRoutes"
- "api/routergetList后端路由模式"
- "configauthentication/rolesControl"
- "plugin-vabgp.$baseMessage后端路由格式异常提示"
acceptance:
- "前端路由模式下setRoutes() 后 routes 可用于菜单渲染"
- "后端路由模式下getList 返回 list 后可 convertRouter 并 resetRouter"
pitfalls:
- "后端路由 list 格式必须符合 convertRouter 预期;否则会提示错误"

View File

@@ -0,0 +1,36 @@
# Module Specstore-settings全局配置/主题/布局状态)
module:
id: store-settings
name: Settings Store主题/布局/语言/折叠等全局配置)
type: store
entrypoints:
- src/store/modules/settings.ts
public_api:
concept:
- "集中管理全局配置theme、device、collapse、language、lock、logo、title"
- "持久化localStoragetheme/collapse/language/..."
- "主题注入updateTheme() 动态加载 scss module 并写入 CSS 变量(--el-*"
usage_examples:
- "useSettingsStore().updateTheme() 在应用启动或主题变更后调用"
- "useSettingsStore().toggleCollapse() 控制侧边栏折叠"
dependency_closure:
runtime:
- "src/config默认 theme/layout/开关项等)"
- "@vueuse/coreuseCssVar如果项目通过 auto-import 或显式引入提供)"
bundler:
- "webpack dynamic requirerequire(`@vab/styles/variables/vab-${themeName}-variables.module.scss`)"
alias:
- "@ -> src"
- "@vab -> library"
acceptance:
- "切换 themeName 后 updateTheme() 能更新 Element Plus CSS 变量"
- "刷新后 theme/collapse/language 等能从 localStorage 恢复"
pitfalls:
- "updateTheme() 使用动态 require scss module非 webpack 构建需替代实现"
- "useCssVar 的来源依赖工程约定(若未自动注入,需要显式 import"

View File

@@ -0,0 +1,24 @@
# Module Specstore-tabs标签页 visitedRoutes
module:
id: store-tabs
name: Tabs StorevisitedRoutes 管理)
type: store
entrypoints:
- src/store/modules/tabs.ts
public_api:
concept:
- "addVisitedRoute/delVisitedRoute/delOthers/delLeft/delRight/delAll"
- "确保至少存在一个 noClosable tab默认第一个"
dependency_closure:
runtime:
- "router typesVabRouteRecord/#/router"
acceptance:
- "路由切换时 addVisitedRoute 可累积标签页"
- "关闭/关闭其它/左右/全部等操作不报错"
pitfalls:
- "对 meta 合并有特殊逻辑dynamicNewTab/noClosable迁移时避免改坏行为"

View File

@@ -0,0 +1,31 @@
# Module Specstore-user登录/用户信息/登出/重置)
module:
id: store-user
name: User Store登录/用户信息/登出/重置)
type: store
entrypoints:
- src/store/modules/user.ts
public_api:
concept:
- "login/socialLogin登录并 afterLogin通知、设置 token"
- "getUserInfo拉取 username/avatar/roles/permissions 并写入 acl"
- "logout/resetAll清空 token/acl/routes/tabs 并 resetRouter"
dependency_closure:
runtime:
- "api/userlogin/getUserInfo/logout/socialLogin"
- "utils/tokengetToken/setToken/removeToken"
- "configtokenName"
- "storeacl/routes/tabs/settings 联动"
- "routerresetRouter"
- "plugin-vabgp.$baseNotify/$baseMessage提示"
acceptance:
- "登录成功后 token 写入并能继续请求"
- "getUserInfo 后 acl 中 roles/permissions 生效"
- "logout 后 resetAll 清理完成且路由重置"
pitfalls:
- "logout 内含 location.reload迁移到新项目需确认是否保留该行为"

View File

@@ -0,0 +1,22 @@
# Module Specstyleslibrary/styles全局样式/变量/背景)
module:
id: styles
name: 样式体系(全局样式 + 变量 + 背景)
type: ui
entrypoints:
- library/styles/vab.scss
- library/styles/variables/
- library/styles/background/
public_api:
concept:
- "vab.scss 是全局样式入口normalize/transition/变量等聚合)"
- "variables 下含布局变量与 Theme 变量vab-*-variables.module.scss"
dependency_closure:
bundler:
- "scss/sass loader由 Vue CLI 提供)"
acceptance:
- "引入 vab.scss 后基础样式生效,不影响 Element Plus"

View File

@@ -0,0 +1,27 @@
# Module Specui-componentsVab 组件库总览)
module:
id: ui-components
name: Vab 组件库library/components/Vab*
type: ui
entrypoints:
- library/components/
public_api:
concept:
- "每个组件目录对应一个 Vab* 组件族;复用优先按目录整包搬运"
dependency_closure:
runtime:
- "Element Plus大量 el-* 依赖)"
- "iconsvab-icons 与 @element-plus/icons-vue常通过 setupVab 全局注册)"
- "全局样式library/styles/vab.scss"
alias:
- "@ -> src"
- "@vab -> library"
acceptance:
- "目标项目能渲染组件(至少 smoke render"
pitfalls:
- "部分组件可能依赖路由、store、权限指令等全局插件抽取前必须列出依赖闭包"

View File

@@ -0,0 +1,27 @@
# Module Specvab-app-main主内容区联动 routes store
module:
id: vab-app-main
name: VabAppMain主内容区
type: ui
entrypoints:
- library/components/VabAppMain/index.vue
public_api:
concept:
- "监听 route 变化,更新 routes store 的 tab/activeMenu"
- "渲染 vab-router-view + vab-footer"
dependency_closure:
runtime:
- "vue-routeruseRoute"
- "store-routestab/activeMenu"
- "utils/routeshandleActivePath"
- "组件依赖VabRouterView、VabFooter需同时可用/注册)"
acceptance:
- "路由变化时 activeMenu.data 更新为当前激活路径"
- "主内容区能渲染 router-view 与 footer"
pitfalls:
- "tab 使用 route.matched[0].name若路由层级/匹配为空需要在目标项目确认兼容"

View File

@@ -0,0 +1,21 @@
# Module SpecVabApp
module:
id: vab-app
name: VabApp应用壳/全局容器)
type: ui
entrypoints:
- library/components/VabApp/index.vue
- library/components/VabApp/
usage_examples:
- "App 根组件中使用 <vab-app /> 作为应用容器"
dependency_closure:
runtime:
- "可能依赖 router-view 与 Element Plus ConfigProvider由 VabApp 内部决定)"
- "可能依赖 pwa / i18n / route meta"
acceptance:
- "渲染不报错"
- "路由切换正常(若内部包含 router-view"

View File

@@ -0,0 +1,28 @@
# Module Specvab-avatar用户头像下拉
module:
id: vab-avatar
name: VabAvatar用户头像/用户名下拉)
type: ui
entrypoints:
- library/components/VabAvatar/index.vue
public_api:
concept:
- "右上角用户头像下拉:个人中心/外链/退出登录,并在退出后跳转到登录页(携带回跳参数)"
dependency_closure:
runtime:
- "store-useravatar/username/logout()"
- "vue-routeruseRoute/useRouter"
- "utils/routestoLoginRoute(fullPath)"
- "i18ntranslate()"
- "Element Plusel-dropdown/el-dropdown-menu/el-dropdown-item/el-avatar"
- "VabIcon"
acceptance:
- "下拉可见时箭头激活态切换"
- "点击退出登录会调用 userStore.logout() 并跳转 toLoginRoute(route.fullPath)"
pitfalls:
- "依赖 userStore 提供 avatar/username新项目需保证字段一致"

View File

@@ -0,0 +1,28 @@
# Module Specvab-breadcrumb面包屑
module:
id: vab-breadcrumb
name: VabBreadcrumb面包屑
type: ui
entrypoints:
- library/components/VabBreadcrumb/index.vue
public_api:
concept:
- "根据 routesStore.getRoutes + 当前 route.path 生成面包屑,并支持 meta.icon/meta.isCustomSvg"
dependency_closure:
runtime:
- "store-routesgetRoutes"
- "vue-routeruseRoute"
- "utils/routeshandleMatched(routes, path)"
- "i18ntranslate()"
- "Element Plusel-breadcrumb/el-breadcrumb-item"
- "VabIcon"
acceptance:
- "meta.breadcrumbHidden=true 的路由不出现在面包屑"
- "每个 crumb 的跳转目标使用 item.redirect若存在"
pitfalls:
- "依赖后端路由结构与 meta 字段title/icon/isCustomSvg"

View File

@@ -0,0 +1,25 @@
# Module Specvab-card卡片封装 + Skeleton
module:
id: vab-card
name: VabCard卡片封装
type: ui
entrypoints:
- library/components/VabCard/index.vue
public_api:
concept:
- "对 el-card 的轻封装header slot/prop + 可选 skeleton loading默认 500ms 结束)"
dependency_closure:
runtime:
- "Element Plusel-card/el-skeleton"
- "vue-routeronBeforeRouteLeave清理定时器"
- "SCSS$base-transition"
acceptance:
- "skeleton=true 时先显示 skeleton再渲染默认 slot"
- "路由离开时清理 timer"
pitfalls:
- "skeletonRows 注释提示:显示数量可能比传入多 1Element Plus 行为)"

View File

@@ -0,0 +1,24 @@
# Module Specvab-colorful-card渐变卡片
module:
id: vab-colorful-card
name: VabColorfulCard渐变卡片
type: ui
entrypoints:
- library/components/VabColorfulCard/index.vue
public_api:
concept:
- "基于 el-card 的渐变背景卡片:支持 header 标题与右上角 icon"
dependency_closure:
runtime:
- "Element Plusel-card"
- "VabIcon可选"
acceptance:
- "传入 colorFrom/colorTo 时背景为 linear-gradient"
- "传入 icon 时显示 vab-icon"
pitfalls:
- "colorFrom/colorTo 需为合法 CSS color 字符串"

View File

@@ -0,0 +1,31 @@
# Module Specvab-column-bar列式布局左侧 Tab + 二级菜单)
module:
id: vab-column-bar
name: VabColumnBarColumn 布局列栏)
type: ui
entrypoints:
- library/components/VabColumnBar/index.vue
public_api:
concept:
- "Column 布局专用:左侧 tabs 切换顶级菜单,右侧 el-menu 渲染 partialRoutes二级菜单"
dependency_closure:
runtime:
- "store-settingstheme(layout/columnStyle)/collapse + foldSideBar/openSideBar"
- "store-routestab/tabMenu/activeMenu/routes/partialRoutes"
- "configdefaultOpeneds/openFirstMenu/uniqueOpened"
- "vue-routeruseRoute/useRouter"
- "utils/validateisExternal"
- "i18ntranslate()"
- "styles@vab/styles/variables/variables.module.scsscolumn-second-menu-background 等)"
- "Element Plusel-scrollbar/el-tabs/el-tab-pane/el-menu/el-divider"
- "VabLogo/VabMenu/VabIcon"
acceptance:
- "theme.layout==='column' 时可用route.meta.noColumn=true 时会自动折叠侧边栏并隐藏 fold-unfold"
- "点击 tab若 tabMenu.path 为外链则 window.open否则openFirstMenu=true跳转到 redirect 或自身"
pitfalls:
- "直接操作 DOMdocument.querySelector('.fold-unfold') 修改 style新项目结构不同需适配"

View File

@@ -0,0 +1,28 @@
# Module Specvab-error-log错误日志展示入口
module:
id: vab-error-log
name: VabErrorLog错误日志展示
type: ui
entrypoints:
- library/components/VabErrorLog/index.vue
public_api:
concept:
- "展示 errorLogs 数量徽标,点击打开弹窗列表"
- "提供清空日志入口clearErrorLog"
dependency_closure:
runtime:
- "store-errorloguseErrorLogStoreerrorLogs/clearErrorLog"
- "Element Plusel-badge/el-dialog/el-table/el-tag/el-popover/el-button"
- "VabIcon全局组件由 setup-vab 注册)"
related_modules:
- "plugin-errorlog负责把运行时错误写入 store否则列表为空"
acceptance:
- "errorLogs.length > 0 时显示徽标并可打开弹窗"
- "点击 '暂不显示' 能清空 store"
pitfalls:
- "仅负责展示;日志产生依赖 plugin/request 链路"

View File

@@ -0,0 +1,20 @@
# Module Specvab-fold折叠按钮
module:
id: vab-fold
name: VabFold侧边栏折叠/展开)
type: ui
entrypoints:
- library/components/VabFold/index.vue
public_api:
concept:
- "根据 settings.collapse 展示不同图标,并触发 settings.toggleCollapse()"
dependency_closure:
runtime:
- "store-settingscollapse/toggleCollapse"
- "VabIcon"
acceptance:
- "点击后触发 toggleCollapse 并切换图标"

View File

@@ -0,0 +1,25 @@
# Module Specvab-footer页脚
module:
id: vab-footer
name: VabFooter页脚
type: ui
entrypoints:
- library/components/VabFooter/index.vue
public_api:
concept:
- "展示年份与站点 title来自 settings store"
dependency_closure:
runtime:
- "store-settingstitle"
- "VabIcon"
styles:
- "SCSS 变量:$base-padding / $base-border-color来自 styles 模块)"
acceptance:
- "渲染后能显示年份与 title"
pitfalls:
- "样式依赖全局 SCSS 变量;目标项目缺失变量会导致样式编译失败"

View File

@@ -0,0 +1,24 @@
# Module Specvab-full-screen全屏切换
module:
id: vab-full-screen
name: VabFullScreen全屏切换
type: ui
entrypoints:
- library/components/VabFullScreen/index.vue
public_api:
concept:
- "点击图标切换全屏状态useFullscreen().toggle"
dependency_closure:
runtime:
- "@vueuse/coreuseFullscreen若项目通过 auto-import 或显式引入提供)"
- "store-settingstheme.showFullScreen"
- "VabIcon"
acceptance:
- "theme.showFullScreen=true 时显示图标,点击可进入/退出全屏"
pitfalls:
- "useFullscreen 的来源依赖工程约定(自动导入 vs 显式 import"

View File

@@ -0,0 +1,21 @@
# Module SpecVabHeader
module:
id: vab-header
name: VabHeader头部导航
type: ui
entrypoints:
- library/components/VabHeader/index.vue
- library/components/VabHeader/
usage_examples:
- "布局组件中使用 VabHeader承载用户信息/语言切换/全屏/刷新等入口"
dependency_closure:
runtime:
- "可能依赖 settings storefixedHeader/showTabs 等)"
- "可能依赖 i18n、router"
acceptance:
- "渲染不报错"
- "常用操作(如全屏/刷新/语言切换)不崩溃(若组件支持)"

View File

@@ -0,0 +1,28 @@
# Module Specvab-language语言切换
module:
id: vab-language
name: VabLanguage语言切换
type: ui
entrypoints:
- library/components/VabLanguage/index.vue
public_api:
concept:
- "通过下拉菜单切换语言:更新 settings.language + i18n locale + document.title"
dependency_closure:
runtime:
- "store-settingstheme.showLanguage / changeLanguage(language)"
- "vue-i18nuseI18n().locale"
- "vue-routeruseRoute读取 route.meta.title"
- "utils/pageTitlegetPageTitle"
- "Element Plusel-dropdown/el-dropdown-menu/el-dropdown-item"
- "VabIcon"
acceptance:
- "theme.showLanguage=true 时显示入口"
- "切换后 settings.language 与 i18n locale 同步更新"
pitfalls:
- "document.title 依赖 route.meta.title目标项目若 meta.title 缺失需适配"

View File

@@ -0,0 +1,21 @@
# Module Specvab-link智能链接
module:
id: vab-link
name: VabLink外链/内链统一)
type: ui
entrypoints:
- library/components/VabLink/index.vue
public_api:
concept:
- "根据 isExternal(to) 自动选择渲染 a 或 router-link"
dependency_closure:
runtime:
- "utils/validateisExternal"
- "vue-routerrouter-link"
acceptance:
- "外链target=_blank + rel=noopener"
- "内链:透传 to 给 router-link"

View File

@@ -0,0 +1,29 @@
# Module Specvab-lock锁屏/解锁)
module:
id: vab-lock
name: VabLock屏幕锁
type: ui
entrypoints:
- library/components/VabLock/index.vue
public_api:
concept:
- "点击锁屏图标将 settings.lock 置为 true并隐藏侧边栏 DOM"
- "解锁通过表单校验后将 settings.lock 置为 false并恢复侧边栏"
dependency_closure:
runtime:
- "store-settingstheme.showLock / lock / title / handleLock / handleUnLock"
- "store-useravatar"
- "i18ntranslate"
- "Element Plusel-avatar/el-form/el-form-item/el-input/el-button"
- "浏览器 DOMdocument.querySelector('.vab-side-bar')(直接改 style"
acceptance:
- "theme.showLock=true 时显示锁图标;点击后 lock=true 并出现锁屏层"
- "解锁成功后 lock=false页面恢复"
pitfalls:
- "组件内密码校验为固定值(示例逻辑);迁移到新项目需确认是否替换为真实策略"
- "直接操作 '.vab-side-bar' DOM若目标项目侧边栏类名不同需要适配"

View File

@@ -0,0 +1,26 @@
# Module Specvab-logoLogo + Title
module:
id: vab-logo
name: VabLogoLogo/标题)
type: ui
entrypoints:
- library/components/VabLogo/index.vue
public_api:
concept:
- "读取 settings.logo/settings.title并根据 theme.layout 渲染不同样式的 logo 区域"
dependency_closure:
runtime:
- "store-settingstheme/layout + logo + title"
- "vue-routerrouter-link"
- "VabIcon自定义 svgis-custom-svg"
- "SCSS$base-header-height/$base-logo-height/$base-title-color 等"
acceptance:
- "logo 存在时使用 vab-icon 渲染自定义 svg"
- "theme.layout==='horizontal' 时标题可隐藏hidden-xs-only"
pitfalls:
- "Column 布局会固定定位 logo依赖左侧菜单宽度相关变量"

View File

@@ -0,0 +1,39 @@
# Module SpecVabMenu
module:
id: vab-menu
name: VabMenu菜单体系
type: ui
entrypoints:
- library/components/VabMenu/index.vue
- library/components/VabMenu/components/VabMenuItem.vue
- library/components/VabMenu/components/VabSubMenu.vue
public_api:
concept:
- "递归渲染菜单VabMenu 根据子路由可见性选择渲染 VabSubMenu 或 VabMenuItem"
- "点击菜单:根据 meta.target/_blank、外链/内链、同路由刷新等逻辑进行跳转或触发 reload"
usage_examples:
- "布局组件中引入 VabMenu配合路由 meta 与权限渲染导航"
dependency_closure:
runtime:
- "vue-routeruseRoute/useRouter跳转/判断当前路由)"
- "store-settingscollapse/device/theme(layout) + foldSideBar移动端点击收起"
- "plugin-vabinject('$pub')(同路由点击触发 $pub('reload-router-view')"
- "configisHashRouterModehash 模式下 _blank 打开内部路由)"
- "utils/validateisExternal外链判断"
- "i18ntranslate菜单 title"
- "Element Plusel-menu-item/el-sub-menu/el-tag"
- "VabIcon"
acceptance:
- "item.children 中存在可见子路由时渲染 VabSubMenu否则渲染 VabMenuItem"
- "meta.target === '_blank' 时按外链/内链规则在新窗口打开"
- "点击当前已激活路由时触发 $pub('reload-router-view')"
pitfalls:
- "组件内部使用 webpack require.context 自动注册子组件;迁移到非 webpack 构建器需等效替代"
- "Element Plus 关于 teleported 的历史兼容问题:弹层渲染到 body 下时需要全局样式配合(见 VabMenu/index.vue 注释)"
- "如果菜单权限依赖 ACL/指令v-permissions/hasPermission迁移时必须把相关依赖一起带走"

View File

@@ -0,0 +1,29 @@
# Module Specvab-nav顶部导航条聚合
module:
id: vab-nav
name: VabNav顶部导航条
type: ui
entrypoints:
- library/components/VabNav/index.vue
public_api:
concept:
- "顶部导航聚合左侧Fold + Tabs/Breadcrumb右侧ErrorLog/Lock/Search/Notice/FullScreen/Language/Theme/Refresh/Avatar"
dependency_closure:
runtime:
- "store-routestab/tabMenu/routes"
- "vue-routeruseRouter"
- "utils/validateisExternal"
- "configopenFirstMenu"
- "i18ntranslate()"
- "Element Plusel-row/el-col/el-tabs/el-tab-pane"
- "ComponentsVabFold/VabBreadcrumb/VabErrorLog/VabLock/VabSearch/VabNotice/VabFullScreen/VabLanguage/VabTheme/VabRefresh/VabAvatar"
acceptance:
- "layout='comprehensive' 时显示顶部 tabs否则显示面包屑hidden-xs-only"
- "点击 tab外链 window.open否则openFirstMenu=true跳 redirect 或自身"
pitfalls:
- "强依赖多组件与 routesStore 输出结构;抽取时必须把依赖组件闭包一起带走"

View File

@@ -0,0 +1,31 @@
# Module Specvab-notice消息中心
module:
id: vab-notice
name: VabNotice消息中心/通知)
type: ui
entrypoints:
- library/components/VabNotice/index.vue
public_api:
concept:
- "显示通知 badge弹出 popover + tabs 展示通知/邮件"
- "从 api/notice.getList 拉取数据并计算 badge"
- "提供清空消息入口(仅清空前端列表与 badge并提示"
dependency_closure:
runtime:
- "store-settingstheme.showNotice"
- "api/noticegetList"
- "plugin-vab$baseMessage清空提示通过 inject 获取)"
- "i18ntranslate"
- "Element Plusel-badge/el-popover/el-tabs/el-tab-pane/el-scrollbar/el-avatar/el-button"
- "VabIcon"
acceptance:
- "theme.showNotice=true 时显示通知入口与 badge"
- "点击/切换 tab 会触发 fetchData 更新列表"
pitfalls:
- "数据协议依赖 notice.getList 的返回结构list/total"
- "清空仅影响前端状态,不等价于后端已读/删除"

View File

@@ -0,0 +1,29 @@
# Module Specvab-query-form查询表单布局容器
module:
id: vab-query-form
name: VabQueryForm查询条件容器
type: ui
entrypoints:
- library/components/VabQueryForm/index.vue
- library/components/VabQueryForm/components/VabQueryFormTopPanel.vue
- library/components/VabQueryForm/components/VabQueryFormBottomPanel.vue
- library/components/VabQueryForm/components/VabQueryFormLeftPanel.vue
- library/components/VabQueryForm/components/VabQueryFormRightPanel.vue
public_api:
concept:
- "基于 Element Plus el-row 的 slot 容器,用于统一查询表单布局与间距"
dependency_closure:
runtime:
- "Element Plusel-row"
styles:
- "SCSS 变量:$base-input-height / $base-margin来自全局样式变量体系见 styles 模块)"
acceptance:
- "作为容器包裹 el-form-item/el-button 时布局与间距符合预期"
pitfalls:
- "样式依赖全局 SCSS 变量;目标项目若未引入对应变量会导致样式编译失败"

View File

@@ -0,0 +1,25 @@
# Module Specvab-refresh刷新当前路由视图
module:
id: vab-refresh
name: VabRefresh刷新按钮
type: ui
entrypoints:
- library/components/VabRefresh/index.vue
public_api:
concept:
- "点击后通过事件总线发布 reload-router-view刷新当前 router-view 缓存"
dependency_closure:
runtime:
- "store-settingstheme.showRefresh是否显示按钮"
- "plugin-vab$pub发布事件"
related_modules:
- "vab-router-view订阅并处理 reload-router-view"
acceptance:
- "theme.showRefresh=true 时显示图标,点击触发 $pub('reload-router-view')"
pitfalls:
- "未安装 plugin-vab 或未接入 vab-router-view 时,点击不会产生效果"

View File

@@ -0,0 +1,31 @@
# Module Specvab-router-view路由视图壳keep-alive + 过渡 + reload 事件)
module:
id: vab-router-view
name: VabRouterViewrouter-view + keep-alive + reload
type: ui
entrypoints:
- library/components/VabRouterView/index.vue
public_api:
concept:
- "统一承载页面 router-view提供 keep-alive include 列表与过渡动画"
- "监听事件总线reload-router-view用于刷新当前视图缓存"
dependency_closure:
runtime:
- "vue-routeruseRoute / <router-view>"
- "plugin-vab$sub/$unsub事件订阅"
- "store-settingstheme.showProgressBar / theme.showPageTransition"
- "store-tabsvisitedRoutes生成 keepAliveNameList"
- "utils/routeshandleActivePath生成 routerKey"
- "configkeepAliveMaxNum"
- "nprogress显示刷新进度条"
acceptance:
- "路由切换时 keep-alive include 列表随 visitedRoutes 更新"
- "$sub('reload-router-view') 触发后当前视图能被重新渲染routerKey 变更)"
pitfalls:
- "存在 get-code 事件并依赖组件的 __source 字段;不同构建/插件下可能不存在"
- "未安装 plugin-vab 时 $sub/$unsub 不存在reload/get-code 事件不会工作"

View File

@@ -0,0 +1,30 @@
# Module Specvab-search菜单搜索Ctrl/⌘+K
module:
id: vab-search
name: VabSearch菜单搜索
type: ui
entrypoints:
- library/components/VabSearch/index.vue
public_api:
concept:
- "通过 Ctrl/⌘+K 或点击图标打开搜索面板teleport 到 body"
- "从 routes store 的 getRoutes 平铺菜单项并模糊搜索"
- "维护本地搜索历史 localStorage(key=vab_search_history)"
dependency_closure:
runtime:
- "store-routesgetRoutes菜单路由来源"
- "vue-routeruseRouterrouter.push 内链跳转)"
- "浏览器 APIwindow.addEventListener('keydown'), navigator.userAgent, localStorage"
- "VabIcon搜索图标与历史删除图标"
acceptance:
- "Ctrl/⌘+K 可打开/关闭面板Escape 关闭)"
- "输入关键字能过滤菜单并 Enter 跳转"
- "搜索历史能写入/删除/清空"
pitfalls:
- "该组件包含较多样式与 DOM 交互teleport/fixed mask抽取到新项目需确保全局样式/层级不冲突"
- "菜单来源依赖 routes store 已完成 setRoutes否则列表为空"

View File

@@ -0,0 +1,20 @@
# Module SpecVabSideBar
module:
id: vab-sidebar
name: VabSideBar侧边栏容器
type: ui
entrypoints:
- library/components/VabSideBar/index.vue
- library/components/VabSideBar/
usage_examples:
- "在布局中使用 VabSideBar 包裹 VabMenu实现侧边导航"
dependency_closure:
runtime:
- "settings storecollapse/device 等"
- "Element Plus如内部使用 el-scrollbar 等)"
acceptance:
- "折叠状态切换后布局不崩溃"

View File

@@ -0,0 +1,21 @@
# Module SpecVabTabs
module:
id: vab-tabs
name: VabTabs多标签页/导航标签)
type: ui
entrypoints:
- library/components/VabTabs/index.vue
- library/components/VabTabs/
usage_examples:
- "布局头部或主区域放置 VabTabs展示已访问路由并支持关闭/切换"
dependency_closure:
runtime:
- "vue-router监听路由变化"
- "storetabs 状态(如果实现依赖 store 模块)"
acceptance:
- "访问多个路由后能出现多个 tab如功能支持"
- "切换/关闭 tab 不崩溃"

View File

@@ -0,0 +1,40 @@
# Module Specvab-theme主题系统入口与交互
module:
id: vab-theme
name: VabTheme主题配置入口/抽屉/设置面板)
type: ui
entrypoints:
- library/components/VabTheme/index.vue
- library/components/VabTheme/components/VabThemeDrawer.vue
- library/components/VabTheme/components/VabThemeSetting.vue
- library/components/VabTheme/components/
public_api:
concept:
- "VabTheme一个刷子图标入口用于触发打开主题抽屉Drawer"
- "VabThemeDrawer主题抽屉监听事件总线打开/随机主题,并调用 settings store 的 saveTheme/resetTheme/updateTheme"
- "VabThemeSetting右侧固定设置入口主题配置/随机换肤/购买源码/清理缓存),通过事件总线触发行为"
usage_examples:
- "点击 VabTheme 触发 $pub('theme') 打开抽屉"
- "点击 VabThemeSetting 的随机换肤触发 $pub('random-theme')"
dependency_closure:
runtime:
- "Pinia settings storesrc/store/modules/settingstheme.showTheme、saveTheme/resetTheme/updateTheme 等)"
- "事件总线/全局注入library/plugins/vab.ts$pub/$sub/$unsub/$baseLoading 等)"
- "i18n translatesrc/i18n/index.ts组件内调用 translate"
- "Element PlusDrawer/Radio/Select/Button 等"
styles:
- "主题变量library/styles/variables/vab-*-variables.module.scssupdateTheme() 动态注入 CSS 变量)"
acceptance:
- "页面渲染包含主题入口(刷子图标)"
- "触发 $pub('theme') 时抽屉能打开;关闭时不报错"
- "保存/重置主题后调用 updateTheme() 生效CSS 变量与 body class 变化)"
pitfalls:
- "Theme 依赖 $pub/$sub 注入;若未安装 vab 插件,事件不会触发"
- "settings.updateTheme() 依赖 webpack 的 require 动态引入 scss module迁移到非 webpack 环境需等效实现"
- "移动端(<992某些操作会触发 reload抽取时需确认期望行为"