wc24 2b33bca681 v0.3.0: 单 sources 入口 + 路径后缀覆盖约定
破坏性重构。框架对外只暴露一个 `sources` glob 入口,消费侧任何 .vue
都按文件路径后缀匹配同后缀覆盖:

- shrimp/components/<name>.vue 同后缀覆盖框架内置(login/layout/topbar/ShrimpTable/...)
- shrimp/components/fields/Field<X>.vue 注册类型 <x>(首字母小写)
- shrimp/module/<key>.vue 业务模块

变更:
- 删除 customFields / moduleSources / overrideField / registerField 旧入口
- 删除 fieldOverrides Map,字段表纯靠 glob 扫描注册
- 框架内 .vue 对可覆盖 peer 改用 defineAsyncComponent(resolveVue(...))
  (login → ShrimpLangSwitch / layout → sideM/navMenu/topbar/userbar/logo /
   ShrimpTable → ShrimpEditDrawer/ShrimpFilterDrawer/...)
- views/ 全部并入 components/,App.vue 上提到 src/ 根
- LangSwitch → ShrimpLangSwitch,PowerTree → ShrimpPowerTree
- module/FieldRelativeTime.vue → components/fields/FieldRelativeTime.vue
- module/user.vue 改用 #column-updatedAt slot 替代旧的 overrideField

字段类型约定从 'field' + Name 改为 lowercase-first(FieldString → 'string'),
内置和消费侧统一。
2026-05-25 15:05:16 +08:00

shrimp-admin

Shrimp 框架前端 —— 一种经典解决方案(不是框架本身),消费 shrimp-server 暴露的 ShrimpServer 路由契约 + ShrimpTable 数据形状契约,基于 Vue 3 + Element Plus 实现一套可直接用的后台壳。

如果你想换 UI 库或者换前端技术栈,直接照 shrimp-server 的约定再写一份就行,不依赖本包。

安装

npm i git+http://git.zeromvc.com/wc24/shrimp-admin.git#v0.3.0

shrimp-admin 是源码 ship(.ts + .vue 直接发),由消费侧 Vite 编译。

使用

// main.ts
import { createApp } from 'vue'
import { createShrimpAdmin, App } from 'shrimp-admin'
import 'shrimp-admin/style'
import zhCn from './locales/zh-cn.json'
import en from './locales/en.json'

const app = createApp(App)
app.use(createShrimpAdmin({
    config: {
        API_URL: '/admin-api',
        TIMEOUT: 10000,
    },
    locales: { 'zh-cn': zhCn, en },
    sources: import.meta.glob('./shrimp/**/*.vue'),
}))
app.mount('#app')

唯一约定: sources 路径后缀覆盖

消费侧把所有要交给框架的 .vue 通过单个 sources 入口注入(import.meta.glob 必须由消费侧自己调用,vite 静态扫描相对调用文件)。框架按文件路径后缀匹配,同后缀消费侧优先,内置兜底。

项目/
└── src/shrimp/                       消费侧目录,可任意命名
    ├── components/
    │   ├── login.vue                 覆盖框架内置 login 页
    │   ├── topbar.vue                覆盖顶栏
    │   └── fields/
    │       └── FieldRelativeTime.vue 注册字段类型 relativeTime
    └── module/
        ├── product.vue               业务模块,routed by moduleKey
        └── user/
            └── orders.vue            子模块,parent=user

框架内置 slot(可覆盖,suffix 列表)

components/login.vue           components/404.vue            components/layout.vue
components/logo.vue            components/navMenu.vue        components/sideM.vue
components/topbar.vue          components/userbar.vue
components/ShrimpLangSwitch.vue           components/ShrimpPowerTree.vue
components/ShrimpTable.vue                components/ShrimpEditDrawer.vue
components/ShrimpFilterDrawer.vue         components/ShrimpFilterTrigger.vue
components/ShrimpSearchInput.vue
components/fields/Field{String,Boolean,Date,Json,Number,Password,Relation,Select,Tab,Textarea,RelativeTime}.vue

字段类型注册

components/fields/Field<X>.vue 自动注册类型 <x>(首字母小写):

文件 type 注册键
FieldString.vue string
FieldRelativeTime.vue relativeTime
你自己的 FieldMyType.vue myType

后端 moduleInfo 里 field.type === 'myType' 时就用你这个组件。

业务模块

components/X.vue 命中 moduleKey === 'X' 的路由,自动作为内容页。子表用嵌套目录(module/<parent>/<sub>.vue)。

消费的契约

参见 shrimp-server README ## 约定 章节。本包消费以下条件契约:

  • ShrimpTable: list 响应 {list,total,page,pageSize,totalPages} / 字段 type 枚举 / populate ${key}_label
  • ShrimpServer: HTTP 路由 / JWT Bearer / IUserAccessor 返回的 powers
S
Description
No description provided
Readme
221 KiB
Languages
Vue 56%
TypeScript 30.3%
SCSS 12.3%
JavaScript 1.4%