vue
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese@json-render/vue
@json-render/vue
Vue 3 renderer that converts JSON specs into Vue component trees with data binding, visibility, and actions.
一款Vue 3渲染器,可将JSON规范转换为具备数据绑定、可见性控制和动作处理能力的Vue组件树。
Installation
安装
bash
npm install @json-render/vue @json-render/core zodPeer dependencies: and .
vue ^3.5.0zod ^4.0.0bash
npm install @json-render/vue @json-render/core zod对等依赖: 和 。
vue ^3.5.0zod ^4.0.0Quick Start
快速开始
Create a Catalog
创建组件目录
typescript
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() }),
description: "A card container",
},
Button: {
props: z.object({ label: z.string(), action: z.string() }),
description: "A clickable button",
},
},
actions: {},
});typescript
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() }),
description: "A card container",
},
Button: {
props: z.object({ label: z.string(), action: z.string() }),
description: "A clickable button",
},
},
actions: {},
});Define Registry with h() Render Functions
使用h()渲染函数定义注册中心
typescript
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,
]),
Button: ({ props, emit }) =>
h("button", { onClick: () => emit("press") }, props.label),
},
});typescript
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,
]),
Button: ({ props, emit }) =>
h("button", { onClick: () => emit("press") }, props.label),
},
});Render Specs
渲染规范
vue
<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>vue
<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>Providers
提供者组件
| Provider | Purpose |
|---|---|
| Share state across components (JSON Pointer paths). Accepts |
| Handle actions dispatched via the event system |
| Enable conditional rendering based on state |
| Form field validation |
| 提供者 | 用途 |
|---|---|
| 在组件间共享状态(支持JSON指针路径)。接受 |
| 处理通过事件系统分发的动作 |
| 支持基于状态的条件渲染 |
| 表单字段验证 |
Composables
组合式函数
| Composable | Purpose |
|---|---|
| Access state context ( |
| Get single value from state |
| Check if a visibility condition is met |
| Access action context |
| Get a single action dispatch function |
| Field validation state |
| Two-way binding for |
Note: returns a — use to access.
useStateStore().stateShallowRef<StateModel>state.value| 组合式函数 | 用途 |
|---|---|
| 访问状态上下文( |
| 从状态中获取单个值 |
| 检查可见性条件是否满足 |
| 访问动作上下文 |
| 获取单个动作的分发函数 |
| 字段验证状态 |
| 为 |
注意:返回类型,需使用访问状态内容。
useStateStore().stateShallowRef<StateModel>state.valueExternal Store (StateStore)
外部状态存储(StateStore)
Pass a to to wire json-render to Pinia, VueUse, or any state management:
StateStoreStateProvidertypescript
import { createStateStore, type StateStore } from "@json-render/vue";
const store = createStateStore({ count: 0 });vue
<StateProvider :store="store">
<Renderer :spec="spec" :registry="registry" />
</StateProvider>将传递给,可将json-render与Pinia、VueUse或任何状态管理库集成:
StateStoreStateProvidertypescript
import { createStateStore, type StateStore } from "@json-render/vue";
const store = createStateStore({ count: 0 });vue
<StateProvider :store="store">
<Renderer :spec="spec" :registry="registry" />
</StateProvider>Dynamic Prop Expressions
动态属性表达式
Props support , , , , . Use on the natural value prop for two-way binding.
$state$bindState$cond$template$computed{ "$bindState": "/path" }属性支持、、、、。在原生值属性上使用可实现双向绑定。
$state$bindState$cond$template$computed{ "$bindState": "/path" }Visibility Conditions
可见性条件
typescript
{ "$state": "/user/isAdmin" }
{ "$state": "/status", "eq": "active" }
{ "$state": "/maintenance", "not": true }
[ cond1, cond2 ] // implicit ANDtypescript
{ "$state": "/user/isAdmin" }
{ "$state": "/status", "eq": "active" }
{ "$state": "/maintenance", "not": true }
[ cond1, cond2 ] // 隐式逻辑与Built-in Actions
内置动作
setStatepushStateremoveStatevalidateFormActionProviderjson
{
"action": "setState",
"params": { "statePath": "/activeTab", "value": "settings" }
}setStatepushStateremoveStatevalidateFormActionProviderjson
{
"action": "setState",
"params": { "statePath": "/activeTab", "value": "settings" }
}Event System
事件系统
Components use to fire events, or for metadata (, ).
emit(event)on(event)shouldPreventDefaultbound组件可使用触发事件,或使用添加元数据(如、)。
emit(event)on(event)shouldPreventDefaultboundStreaming
流式渲染
useUIStreamuseChatUIuseUIStreamuseChatUIBaseComponentProps
BaseComponentProps
For catalog-agnostic reusable components:
typescript
import type { BaseComponentProps } from "@json-render/vue";
const Card = ({ props, children }: BaseComponentProps<{ title?: string }>) =>
h("div", null, [props.title, children]);用于与目录无关的可复用组件:
typescript
import type { BaseComponentProps } from "@json-render/vue";
const Card = ({ props, children }: BaseComponentProps<{ title?: string }>) =>
h("div", null, [props.title, children]);Key Exports
核心导出
| Export | Purpose |
|---|---|
| Create a type-safe component registry from a catalog |
| Render a spec using a registry |
| Element tree schema (from |
| Context providers |
| State composables |
| Action composables |
| Validation and visibility |
| Streaming composables |
| Create in-memory |
| Catalog-agnostic component props type |
| 导出项 | 用途 |
|---|---|
| 从组件目录创建类型安全的组件注册中心 |
| 使用注册中心渲染规范 |
| 元素树 schema(来自 |
| 上下文提供者组件 |
| 状态相关组合式函数 |
| 动作相关组合式函数 |
| 验证与可见性相关函数 |
| 流式渲染组合式函数 |
| 创建内存中的 |
| 与目录无关的组件属性类型 |