关于 vue
@json-render/vue 将 JSON 规格渲染为 Vue 3 组件树,适合在 Vue 项目中构建数据驱动界面的开发者。它提供状态、动作、可见性和验证支持,并可连接外部状态存储。
主要功能
- 01将 JSON 规格渲染为 Vue 组件树
- 02支持状态绑定与动态属性表达式
- 03提供动作、可见性和验证上下文
- 04支持命名插槽与自定义组件注册
- 05可连接外部状态存储
- 06支持流式 UI 规格
适用场景
- 01在 Vue 应用中渲染 JSON 界面规格
- 02根据状态控制组件显示并绑定属性
- 03处理表单验证与组件触发的动作
- 04从 API 流式接收界面规格
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vercel-labs/ json-render --skill vue安装后在 Claude Code 中输入/vue确认已加载。
详细介绍
@json-render/vue
Vue 3 渲染器,可将 JSON 规范转换为 Vue 组件树,并支持数据绑定、可见性和操作。
安装
npm install @json-render/vue @json-render/core zod
Peer 依赖:vue ^3.5.0 和 zod ^4.0.0。
快速开始
创建目录
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/vue/schema";
import { z } from "zod";
export const catalog = defineCatalog(schema, {
components: {
Card: {
props: z.object({ title: z.string(), description: z.string().nullable() }),
slots: ["default"],
description: "A card container",
},
Layout: {
props: z.object({}),
slots: ["default", "header", "footer"],
description: "Layout with named content regions",
},
Button: {
props: z.object({ label: z.string(), action: z.string() }),
description: "A clickable button",
},
},
actions: {},
});
使用 h() 渲染函数定义注册表
import { h } from "vue";
import { defineRegistry } from "@json-render/vue";
import { catalog } from "./catalog";
export const { registry } = defineRegistry(catalog, {
components: {
Card: ({ props, children }) =>
h("div", { class: "card" }, [
h("h3", null, props.title),
props.description ? h("p", null, props.description) : null,
children,
]),
Layout: ({ slots }) =>
h("div", null, [
h("header", null, slots.header?.()),
h("main", null, slots.default?.()),
h("footer", null, slots.footer?.()),
]),
Button: ({ props, emit }) =>
h("button", { onClick: () => emit("press") }, props.label),
},
});
命名插槽
使用 children 作为 "default" 插槽。对于目录中声明的其他插槽名称,请使用元素顶层的 slots 对象:
{
"type": "Layout",
"props": {},
"children": ["main"],
"slots": {
"header": ["heading"],
"footer": ["actions"]
}
}
注册表组件接收 Vue 原生插槽函数。使用 slots.header?.()、slots.footer?.() 等方式渲染。slots.default?.() 会渲染规范中的 children;上下文中的 children 字段是该渲染结果的便捷别名。在 JSON 规范中,请将默认内容放在 children 中,而不要在 slots 中添加 default 条目。
渲染规范
<script setup lang="ts">
import { StateProvider, ActionProvider, Renderer } from "@json-render/vue";
import { registry } from "./registry";
const spec = { root: "card-1", elements: { /* ... */ } };
</script>
<template>
<StateProvider :initial-state="{ form: { name: '' } }">
<ActionProvider :handlers="{ submit: handleSubmit }">
<Renderer :spec="spec" :registry="registry" />
</ActionProvider>
</StateProvider>
</template>
Provider
| Provider | 用途 |
|---|---|
StateProvider | 在组件间共享状态(JSON Pointer 路径)。受控模式下接受 initialState 或 store。 |
ActionProvider | 处理通过事件系统分发的操作 |
VisibilityProvider | 根据状态启用条件渲染 |
ValidationProvider | 表单字段验证 |
组合式函数
| 组合式函数 | 用途 |
|---|---|
useStateStore() | 访问状态上下文(state 为 ShallowRef,以及 get、set、update) |
useStateValue(path) | 获取状态中的单个值 |
useIsVisible(condition) | 检查是否满足可见性条件 |
useActions() | 访问操作上下文 |
useAction(binding) | 获取单个操作分发函数 |
useFieldValidation(path, config) | 字段验证状态 |
useBoundProp(propValue, bindingPath) | 为 $bindState/$bindItem 提供双向绑定 |
注意:useStateStore().state 返回 ShallowRef<StateModel>——使用 state.value 进行访问。
外部 Store(StateStore)
嵌套列表可以在外层 repeat 中将 repeat.statePath 设置为 { "$item": "field" }。
将 StateStore 传递给 StateProvider,即可将 json-render 接入 Pinia、VueUse 或任何状态管理方案:
import { createStateStore, type StateStore } from "@json-render/vue";
const store = createStateStore({ count: 0 });
<StateProvider :store="store">
<Renderer :spec="spec" :registry="registry" />
</StateProvider>
动态 Prop 表达式
Props 支持 $state、$bindState、$cond、$template、$computed。在自然值 prop 上使用 { "$bindState": "/path" } 可实现双向绑定。
可见性条件
{ "$state": "/user/isAdmin" }
{ "$state": "/status", "eq": "active" }
{ "$state": "/maintenance", "not": true }
[ cond1, cond2 ] // implicit AND
内置操作
setState、pushState、removeState 和 validateForm 内置于 Vue schema 中,并由 ActionProvider 处理:
{
"action": "setState",
"params": { "statePath": "/activeTab", "value": "settings" }
}
事件系统
组件使用 emit(event) 触发事件,或使用 on(event) 获取元数据(shouldPreventDefault、bound)。
流式传输
useUIStream 和 useChatUI 会返回 Vue Refs,用于从 API 接收流式规范。
BaseComponentProps
用于不依赖特定目录的可复用组件:
import type { BaseComponentProps } from "@json-render/vue";
const Card = ({ props, children }: BaseComponentProps<{ title?: string }>) =>
h("div", null, [props.title, children]);
主要导出项
| 导出项 | 用途 |
|---|---|
defineRegistry | 根据目录创建类型安全的组件注册表 |
Renderer | 使用注册表渲染规范 |
schema | 元素树 schema(来自 @json-render/vue/schema) |
StateProvider、ActionProvider、VisibilityProvider、ValidationProvider | 上下文 Provider |
useStateStore、useStateValue、useBoundProp | 状态组合式函数 |
useActions、useAction | 操作组合式函数 |
useFieldValidation、useIsVisible | 验证和可见性 |
useUIStream、useChatUI | 流式组合式函数 |
createStateStore | 创建内存中的 StateStore |
BaseComponentProps | 不依赖特定目录的组件 Props 类型 |