@tuoyuan/json-schema
v0.3.1
Published
json-schema编辑器及表单组件,支持 PC 端、移动端、查看器
Readme
@tuoyuan/json-schema 组件
JSON Schema 编辑器及表单组件库,支持 PC 端、移动端、查看器。
✨ 新增特性 (v0.3.0)
- 🎨 Widget 扩展增强:支持 attrsSchema 配置,可视化渲染 widget 属性表单
- 🌍 全局配置:支持
app.use(JsonSchema, { widgets, formWidgets, plugins })全局配置 - 📱 移动端表单:新增
AJsonSchemaFormMobile移动端专用表单组件 - 👀 Schema 查看器:新增
AJsonSchemaViewer组件,树形展示 JSON Schema - 🔌 插件系统:字段插件机制,支持自定义字段增强和展示值格式化
- 📝 枚举增强:支持 enumDescriptions,兼容现有格式和 apifox 格式
- 🎯 自定义扩展字段增强 ✨ 新增:
- 支持 20+ 种字段类型:单行/多行文本、数字、下拉单选/多选、单选/多选按钮组、开关、日期/时间、滑块、评分、颜色选择器、级联选择器、树形选择器、弹窗选择器、文件上传等
- 基于 schema表单规范
- 统一数据类型规范
- 支持动态显示/隐藏/禁用
- 支持自定义校验
- 提供预设字段配置
组件内容
- json-schema-editor - JSON Schema 可视化编辑器
- json-schema-form - PC 端动态表单
- json-schema-form-mobile - 移动端动态表单 ✨ 新增
- json-schema-viewer - Schema 查看器 ✨ 新增
开发
运行
- 运行
pnpm i安装依赖。 - 预览: 在play包下执行
pnpm run dev启动项目预览。 - 打包:
pnpm run build,打包目录为dist。 - 发布:执行
npm publish发布组件库。
环境
node >= 18.20.4 pnpm >= 9
使用
安装
# npm
npm install @tuoyuan/json-schema
# pnpm
pnpm add @tuoyuan/json-schema快速开始
1. 完整引入(推荐)
在 main.ts 中全局注册:
import { createApp } from 'vue'
import App from './App.vue'
// 引入 Arco Design Vue
import ArcoVue from '@arco-design/web-vue'
import '@arco-design/web-vue/dist/arco.css'
// 引入 JSON Schema 组件库
import JsonSchema from '@tuoyuan/json-schema'
import '@tuoyuan/json-schema/dist/es/style.css'
const app = createApp(App)
app.use(ArcoVue)
app.use(JsonSchema)
app.mount('#app')全局注册后,可以直接在任何组件中使用:
<template>
<!-- 1. Schema 编辑器 -->
<AJsonSchemaEditor v-model="schema" />
<!-- 2. PC 端表单 -->
<AJsonSchemaForm v-model="formData" :options="schema" />
<!-- 3. 移动端表单 -->
<AJsonSchemaFormMobile v-model="mobileFormData" :schema="schema" />
<!-- 4. Schema 查看器 -->
<AJsonSchemaViewer :schema="schema" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
const schema = ref({
type: 'object',
properties: {
name: { type: 'string', title: '姓名' }
}
})
const formData = ref({})
const mobileFormData = ref({})
</script>2. 按需引入
直接在组件中导入使用:
<template>
<!-- 使用 Schema 编辑器 -->
<AJsonSchemaEditor v-model="schema" show-mock show-form />
<!-- 使用 PC 端表单 -->
<AJsonSchemaForm v-model="formData" :options="schema" />
<!-- 使用移动端表单 -->
<AJsonSchemaFormMobile v-model="mobileData" :schema="schema" />
<!-- 使用 Schema 查看器 -->
<AJsonSchemaViewer :schema="schema" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
// 按需导入组件
import {
AJsonSchemaEditor,
AJsonSchemaForm,
AJsonSchemaFormMobile,
AJsonSchemaViewer
} from '@tuoyuan/json-schema'
import '@tuoyuan/json-schema/dist/es/style.css'
const schema = ref({
type: 'object',
properties: {
name: {
type: 'string',
title: '姓名',
description: '请输入您的姓名'
},
age: {
type: 'number',
title: '年龄',
minimum: 0,
maximum: 150
},
email: {
type: 'string',
title: '邮箱',
format: 'email'
},
status: {
type: 'string',
title: '状态',
enum: ['active', 'inactive'],
enumDescriptions: {
'active': '激活',
'inactive': '未激活'
}
}
},
required: ['name', 'email'],
order: ['name', 'email', 'age', 'status']
})
const formData = ref({})
const mobileData = ref({})
</script>四个核心组件说明
| 组件名 | 说明 | 使用场景 |
|--------|------|----------|
| AJsonSchemaEditor | JSON Schema 可视化编辑器 | 用于设计和编辑 JSON Schema 结构 |
| AJsonSchemaForm | PC 端动态表单 | 根据 Schema 自动生成桌面端表单 |
| AJsonSchemaFormMobile | 移动端动态表单 | 根据 Schema 自动生成移动端表单 |
| AJsonSchemaViewer | Schema 查看器 | 以树形结构查看 Schema 定义 |
高级配置(可选)
如果需要全局注册自定义 widgets 和插件:
// main.ts
import { createApp } from 'vue'
import ArcoVue from '@arco-design/web-vue'
import '@arco-design/web-vue/dist/arco.css'
import JsonSchema from '@tuoyuan/json-schema'
import type { EditorWidgetItem, JsonSchemaFieldPlugin } from '@tuoyuan/json-schema'
import '@tuoyuan/json-schema/dist/es/style.css'
// 1. 定义全局 widgets(可选)
const globalWidgets: EditorWidgetItem[] = [
{
type: 'my-custom-input',
component: MyCustomInput,
dataType: ['string'],
attrs: { placeholder: '默认占位符' },
// 🎨 attrsSchema:支持可视化配置 widget 属性
attrsSchema: {
type: 'object',
properties: {
placeholder: { type: 'string', title: '占位符' },
maxLength: { type: 'number', title: '最大长度' }
}
}
}
]
// 2. 定义全局插件(可选)
const globalPlugins: JsonSchemaFieldPlugin[] = [
{
id: 'my-plugin',
match: (ctx) => ctx.widgetType === 'my-widget',
enhanceSchema: async (ctx) => {
// 在这里增强 schema
ctx.schema.customField = 'enhanced'
}
}
]
const app = createApp(App)
app.use(ArcoVue)
// 3. 全局注册(可以不传任何参数)
app.use(JsonSchema, {
widgets: globalWidgets, // 可选:全局 editor widgets
formWidgets: [], // 可选:全局 form widgets
plugins: globalPlugins // 可选:全局字段插件
})
app.mount('#app')说明:
widgets: Editor 组件可用的自定义 widgetsformWidgets: Form 组件可用的自定义 widgetsplugins: 全局字段插件,所有组件共享- 如果不需要全局配置,可以直接
app.use(JsonSchema)不传参数
基础引入(不推荐)
import JsonSchema from "@tuoyuan/json-schema";
import type { EditorWidgetItem, JsonSchemaFieldPlugin } from "@tuoyuan/json-schema";
import "@tuoyuan/json-schema/dist/es/style.css";
// 定义全局 widgets
const globalWidgets: EditorWidgetItem[] = [
{
type: 'my-custom-input',
component: MyCustomInput,
dataType: ['string'],
attrs: { placeholder: '默认占位符' },
// 🎨 新增:attrsSchema 支持可视化配置
attrsSchema: {
type: 'object',
properties: {
placeholder: { type: 'string', title: '占位符' },
maxLength: { type: 'number', title: '最大长度' }
}
}
}
];
// 定义全局插件
const globalPlugins: JsonSchemaFieldPlugin[] = [
{
id: 'my-plugin',
match: (ctx) => ctx.widgetType === 'my-widget',
enhanceSchema: async (ctx) => {
// 增强 schema 逻辑
}
}
];
// 全局注册
app.use(JsonSchema, {
widgets: globalWidgets,
formWidgets: [],
plugins: globalPlugins
});组件使用
1. JsonSchemaEditor - Schema 编辑器
<template>
<AJsonSchemaEditor
v-model="schema"
:widgets="localWidgets"
:custom="customFields"
show-mock
show-form
modal-size="large"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { PRESET_CUSTOM_FIELDS } from '@tuoyuan/json-schema'
import type { CustomFieldConfig } from '@tuoyuan/json-schema'
const schema = ref({
type: 'object',
properties: {
name: { type: 'string', title: '姓名' }
}
})
// 使用预设自定义字段
const customFields = PRESET_CUSTOM_FIELDS
// 或自定义配置
const customFields: CustomFieldConfig[] = [
{
name: 'x-category',
title: '字段分类',
type: 'select',
options: [
{ label: '基础信息', value: 'basic' },
{ label: '详细信息', value: 'detail' },
],
},
{
name: 'x-hidden',
title: '是否隐藏',
type: 'switch',
defaultValue: false,
},
]
// 局部 widgets 会与全局 widgets 合并
const localWidgets = []
</script>2. JsonSchemaForm - PC 端表单
<template>
<AJsonSchemaForm
v-model="formData"
:options="schema"
validate-on-change
/>
</template>
<script setup lang="ts">
const formData = ref({})
const schema = ref({
type: 'object',
properties: {
name: { type: 'string', title: '姓名' }
},
required: ['name']
})
</script>3. JsonSchemaFormMobile - 移动端表单 ✨ 新增
<template>
<AJsonSchemaFormMobile
v-model="formData"
:schema="schema"
:plugins="plugins"
/>
</template>
<script setup lang="ts">
const formData = ref({})
const schema = ref({
type: 'object',
properties: {
name: {
type: 'string',
title: '姓名',
widget: {
type: 'a-input',
attrs: { placeholder: '请输入姓名' }
}
},
status: {
type: 'string',
title: '状态',
enum: ['active', 'inactive'],
// 📝 新增:enumDescriptions 支持
enumDescriptions: {
'active': '激活',
'inactive': '未激活'
}
}
},
order: ['name', 'status']
})
</script>4. JsonSchemaViewer - Schema 查看器 ✨ 新增
<template>
<AJsonSchemaViewer :schema="schema" />
</template>
<script setup lang="ts">
const schema = ref({
type: 'object',
properties: {
id: { type: 'integer', title: 'ID' },
status: {
type: 'string',
title: '状态',
enum: ['draft', 'published'],
enumDescriptions: {
'draft': '草稿',
'published': '已发布'
}
}
},
required: ['id']
})
</script>自定义扩展字段 ✨ 新增
支持的字段类型
基于jsonschema表单规范,支持 20+ 种字段类型:
- 基础类型:
string、textarea、number、boolean - 选择类型:
select、multiSelect、radio、checkbox、cascader、treeSelect、modalSelect - 日期时间:
date、datetime、time、dateRange - 特殊类型:
switch、slider、rate、color、upload
快速使用预设字段
import { PRESET_CUSTOM_FIELDS } from '@tuoyuan/json-schema'
// 包含 19 个常用预设字段
const customFields = PRESET_CUSTOM_FIELDS自定义字段配置
import type { CustomFieldConfig } from '@tuoyuan/json-schema'
const customFields: CustomFieldConfig[] = [
// 下拉单选
{
name: 'x-category',
title: '字段分类',
type: 'select',
options: [
{ label: '基础信息', value: 'basic' },
{ label: '详细信息', value: 'detail' },
],
},
// 下拉多选
{
name: 'x-tags',
title: '标签',
type: 'multiSelect',
options: [
{ label: '重要', value: 'important' },
{ label: '必填', value: 'required' },
],
},
// 开关
{
name: 'x-hidden',
title: '是否隐藏',
type: 'switch',
defaultValue: false,
},
// 评分
{
name: 'x-priority',
title: '优先级',
type: 'rate',
rateConfig: {
count: 5,
allowHalf: true,
},
},
// 滑块
{
name: 'x-level',
title: '级别',
type: 'slider',
sliderConfig: {
min: 0,
max: 10,
step: 1,
},
},
// 日期范围
{
name: 'x-date-range',
title: '生效日期',
type: 'dateRange',
},
// 颜色选择器
{
name: 'x-color',
title: '标识颜色',
type: 'color',
defaultValue: '#1890ff',
},
]动态控制
{
name: 'x-advanced',
title: '高级选项',
type: 'string',
// 动态显示/隐藏
visible: (schema) => schema['x-mode'] === 'advanced',
// 动态禁用
disabled: (schema) => schema['x-locked'] === true,
// 自定义校验
validator: (value, schema) => {
if (!value) return '不能为空'
return true
},
}完整文档
查看 自定义扩展字段使用指南 了解详细配置和示例。
Widget 扩展
attrsSchema 配置 ✨ 新增
import type { EditorWidgetItem } from '@tuoyuan/json-schema'
const myWidget: EditorWidgetItem = {
type: 'my-select',
component: MySelectComponent,
dataType: ['string', 'number'],
attrs: {
// 默认属性
options: [],
placeholder: '请选择'
},
// 🎨 attrsSchema:定义属性的可视化配置 schema
attrsSchema: {
type: 'object',
properties: {
placeholder: {
type: 'string',
title: '占位符'
},
multiple: {
type: 'boolean',
title: '是否多选'
},
options: {
type: 'array',
title: '选项列表',
items: {
type: 'object',
properties: {
label: { type: 'string', title: '标签' },
value: { type: 'string', title: '值' }
}
}
}
}
}
}特性:
- 有 attrsSchema 时,编辑器将渲染可视化表单,JSON 输入框保留
- 可视化表单输入的属性与 attrs 深度合并
- 无 attrsSchema 时,使用传统 JSON 输入方式
字段插件系统 ✨ 新增
import type { JsonSchemaFieldPlugin } from '@tuoyuan/json-schema'
const myPlugin: JsonSchemaFieldPlugin = {
id: 'my-plugin',
// 初始化钩子
async init(ctx) {
console.log('Plugin initialized', ctx.mode)
},
// 匹配条件
match(ctx) {
return ctx.widgetType === 'my-custom-widget'
},
// 增强 schema
async enhanceSchema(ctx) {
ctx.schema.enhanced = true
// 可以修改 schema 任何属性
},
// 格式化展示值(用于 display 模式)
formatDisplayValue(ctx) {
if (ctx.fieldValue) {
return `自定义展示: ${ctx.fieldValue}`
}
}
}深度合并 ✨ 新增
attrsSchema 配置的属性会与默认 attrs 深度合并:
// Widget 定义
{
attrs: {
options: [],
style: { color: 'red' }
}
}
// 用户通过可视化表单配置
{
options: [{ label: 'A', value: 'a' }],
style: { fontSize: '14px' }
}
// 最终结果(深度合并)
{
options: [{ label: 'A', value: 'a' }],
style: { color: 'red', fontSize: '14px' }
}工具函数导出
import {
getTrueType, // 获取真实类型
deepMerge, // 深度合并对象 ✨ 新增
deepEqual, // 深度比较
setFormData, // 设置表单数据
resolveDisplayValue, // 解析展示值 ✨ 新增
applyFieldPluginsOnSchema // 应用字段插件 ✨ 新增
} from '@tuoyuan/json-schema'更新日志
查看 CHANGELOG.md 了解详细更新内容。
使用 json-schema 组件之前,应先全量引入 @tuoyuan/web 组件和样式
import TyWeb from "@tuoyuan/web";
import "@tuoyuan/web/es/index.less";