[](https://www.npmjs.com/package/@xiaohaih/json-form-core) [](https://www.npmjs.com/package/@xiaohaih/json
npm install @xiaohaih/json-form-core

@xiaohaih/json-form-core 是 json-form 库的核心模块,提供零 UI 依赖的纯逻辑实现。它通过组合式 API 实现表单项的状态管理、依赖关系追踪、数据源管理等核心功能。
- 🚀 零 UI 依赖: 纯逻辑实现,不依赖任何 UI 框架
- 🔄 组合式 API: 基于 Vue 3 Composition API,支持 Vue 2.7+
- 📦 TypeScript: 完整的类型定义和类型推导
- 🎯 依赖追踪: 智能的字段间依赖关系管理
- 🔍 数据源管理: 支持静态和动态数据源,优先级自动处理
- ✅ 表单校验: 内置简单的全局校验机制,支持异步校验
- 🔗 生命周期钩子: 丰富的钩子函数用于自定义逻辑
- 🧩 模块化设计: 核心功能解耦,支持扩展
``bash使用 pnpm
pnpm add @xiaohaih/json-form-core
🏗️ 架构设计
$3
json-form 采用 组合式架构设计,将表单逻辑与 UI 层完全解耦:
`
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ UI 适配层 │ │ 核心逻辑层 │ │ 业务逻辑层 │
│ │ │ │ │ │
│ • Element Plus │◄──►│ • useWrapper │◄──►│ • 表单配置 │
│ • Element UI │ │ • usePlain │ │ • 数据处理 │
│ • 其他 UI 库 │ │ • 状态管理 │ │ • 业务规则 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
`$3
#### useWrapper (容器组件)
表单容器的核心逻辑,负责:
- 管理整个表单的状态 (
query 对象)
- 协调所有表单项的注册和通信
- 处理搜索事件和校验流程
- 支持 backfill 和 model 双模式#### usePlain (表单项组件)
单个表单项的核心逻辑,负责:
- 管理字段值的状态同步
- 处理依赖关系和级联更新
- 管理数据源的获取和缓存
- 执行字段级校验
🚀 快速开始
$3
`typescript
import { usePlain, useWrapper } from '@xiaohaih/json-form-core';// 1. 创建容器
const wrapperProps = {
backfill: { username: '', status: 'active' },
realtime: true,
onSearch: (query) => {
console.log('搜索条件:', query);
// 执行搜索逻辑
}
};
const wrapper = useWrapper(wrapperProps);
// 2. 创建表单项
const plainProps = {
field: 'username',
query: wrapper.query,
validator: (query) => {
if (!query.username) return '用户名不能为空';
}
};
const plain = usePlain(plainProps);
// 3. 使用
console.log(plain.checked.value); // 获取当前值
plain.change('new value'); // 改变值
wrapper.search(); // 触发搜索
`$3
`typescript
// 省份选择影响城市选项
const provincePlain = usePlain({
field: 'province',
query: wrapper.query,
options: [
{ label: '北京市', value: 'beijing' },
{ label: '上海市', value: 'shanghai' }
]
});const cityPlain = usePlain({
field: 'city',
depend: true,
dependFields: 'province',
getOptions: (cb, query) => {
// 根据省份获取城市列表
fetchCities(query.province).then(cb);
}
});
`📚 API 参考
$3
#### Props
| 属性名 | 类型 | 默认值 | 描述 |
| :--------- | :------------------------------------ | :---------- | :------------------- |
| realtime |
boolean | undefined | 是否实时触发搜索事件 |
| backfill | Record | - | 回填数据 |
| model | Record | - | 双向绑定值 |
| validator | (query: Record | - | 表单级校验函数 |
| toast | (msg: string) => void | - | 校验失败提示 |
| readonly | boolean | - | 表单只读状态 |
| disabled | boolean | - | 表单禁用状态 |#### 返回值
`typescript
interface WrapperExpose {
child: CommonMethod[]; // 已注册的子组件
query: Ref>; // 表单查询对象
search: () => Promise; // 触发搜索
reset: () => void; // 重置表单
validateToast: () => Promise; // 执行校验
}
`$3
#### Props
| 属性名 | 类型 | 默认值 | 描述 |
| :----------- | :-------------------- | :----- | :--------------- |
| field |
string | - | 字段名 |
| query | Record | - | 查询对象 |
| options | any[] | [] | 静态数据源 |
| getOptions | GetOptions | - | 动态数据源函数 |
| depend | boolean | - | 是否依赖其他字段 |
| dependFields | string \| string[] | - | 依赖字段 |
| validator | Validator | - | 字段校验函数 |
| initialValue | any | - | 初始值 |
| defaultValue | any | - | 默认值 |#### 返回值
`typescript
interface PlainExpose {
checked: ComputedRef; // 当前值
loading: Ref; // 加载状态
finalOption: ComputedRef; // 最终数据源
change: (value: any) => void; // 改变值
reset: () => void; // 重置字段
search: () => void; // 触发搜索
}
`🗂️ 目录结构
`
packages/core/
├── index.ts # 入口文件
├── interface.ts # 类型定义
├── version.ts # 版本信息
├── use/ # 核心逻辑
│ ├── index.ts # use 层导出
│ ├── constant.ts # 常量和接口定义
│ ├── wrapper/ # 容器组件逻辑
│ │ ├── index.ts # useWrapper 实现
│ │ ├── types.ts # wrapper 类型定义
│ │ └── README.md # wrapper 文档
│ └── plain/ # 表单项逻辑
│ ├── index.ts # usePlain 实现
│ ├── types.ts # plain 类型定义
│ └── README.md # plain 文档
├── utils/ # 工具函数
│ ├── index.ts # 工具导出
│ └── base.ts # 基础工具
└── README.md # 模块文档
`🔧 开发指南
$3
- Vue: 3.0+ 或 2.7+ 或 @vue/composition-api 支持的版本
- TypeScript: 4.0+
- Node.js: 16+
$3
`json
{
"vue": "^3.0.0-0 || ^2.0.0",
"@vue/composition-api": "^1.0.0-rc.1" // Vue 2.7+ 可选
}
`$3
`bash
构建核心模块
pnpm run build运行测试
pnpm run test
`$3
#### 添加新的表单项类型
1. 在
use/plain/ 目录下实现新的逻辑
2. 在 types.ts 中定义对应的 props
3. 在 UI 适配层使用该逻辑#### 自定义数据源
`typescript
const customPlain = usePlain({
field: 'customField',
getOptions: async (cb, query, option) => {
const data = await fetchCustomData(query);
cb(data); // 可通过 option 控制行为
option.changeDefaultValue(data[0]);
}
});
``欢迎提交 Issue 和 Pull Request!
ISC License