vue

작성자: vercel

Vue 3 렌더러 for json-render. JSON 스펙에서 Vue UI를 구축하거나, @json-render/vue를 사용하거나, Vue 컴포넌트 레지스트리를 정의하거나, 렌더링할 때 사용합니다.

npx skills add https://github.com/vercel-labs/json-render --skill vue

@json-render/vue

Vue 3 renderer that converts JSON specs into Vue component trees with data binding, visibility, and actions.

Installation

npm install @json-render/vue @json-render/core zod

Peer dependencies: vue ^3.5.0 and zod ^4.0.0.

Quick Start

Create a Catalog

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: {},
});

Define Registry with h() Render Functions

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),
  },
});

Named Slots

Use children for the "default" slot. Use the element's top-level slots object for other slot names declared by the catalog:

{
  "type": "Layout",
  "props": {},
  "children": ["main"],
  "slots": {
    "header": ["heading"],
    "footer": ["actions"]
  }
}

Registry components receive Vue-native slot functions. Render them with slots.header?.(), slots.footer?.(), and so on. slots.default?.() renders the spec's children; the children context field is a convenience alias for that rendered result. In the JSON spec, keep default content in children rather than adding a default entry to slots.

Render Specs

<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

ProviderPurpose
StateProviderShare state across components (JSON Pointer paths). Accepts initialState or store for controlled mode.
ActionProviderHandle actions dispatched via the event system
VisibilityProviderEnable conditional rendering based on state
ValidationProviderForm field validation

Composables

ComposablePurpose
useStateStore()Access state context (state as ShallowRef, get, set, update)
useStateValue(path)Get single value from state
useIsVisible(condition)Check if a visibility condition is met
useActions()Access action context
useAction(binding)Get a single action dispatch function
useFieldValidation(path, config)Field validation state
useBoundProp(propValue, bindingPath)Two-way binding for $bindState/$bindItem

Note: useStateStore().state returns a ShallowRef<StateModel> — use state.value to access.

External Store (StateStore)

Nested lists can set repeat.statePath to { "$item": "field" } inside an enclosing repeat.

Pass a StateStore to StateProvider to wire json-render to Pinia, VueUse, or any state management:

import { createStateStore, type StateStore } from "@json-render/vue";

const store = createStateStore({ count: 0 });
<StateProvider :store="store">
  <Renderer :spec="spec" :registry="registry" />
</StateProvider>

Dynamic Prop Expressions

Props support $state, $bindState, $cond, $template, $computed. Use { "$bindState": "/path" } on the natural value prop for two-way binding.

Visibility Conditions

{ "$state": "/user/isAdmin" }
{ "$state": "/status", "eq": "active" }
{ "$state": "/maintenance", "not": true }
[ cond1, cond2 ]  // implicit AND

Built-in Actions

setState, pushState, removeState, and validateForm are built into the Vue schema and handled by ActionProvider:

{
  "action": "setState",
  "params": { "statePath": "/activeTab", "value": "settings" }
}

Event System

Components use emit(event) to fire events, or on(event) for metadata (shouldPreventDefault, bound).

Streaming

useUIStream and useChatUI return Vue Refs for streaming specs from an API.

BaseComponentProps

For catalog-agnostic reusable components:

import type { BaseComponentProps } from "@json-render/vue";

const Card = ({ props, children }: BaseComponentProps<{ title?: string }>) =>
  h("div", null, [props.title, children]);

Key Exports

ExportPurpose
defineRegistryCreate a type-safe component registry from a catalog
RendererRender a spec using a registry
schemaElement tree schema (from @json-render/vue/schema)
StateProvider, ActionProvider, VisibilityProvider, ValidationProviderContext providers
useStateStore, useStateValue, useBoundPropState composables
useActions, useActionAction composables
useFieldValidation, useIsVisibleValidation and visibility
useUIStream, useChatUIStreaming composables
createStateStoreCreate in-memory StateStore
BaseComponentPropsCatalog-agnostic component props type

vercel의 다른 스킬

vercel
vercel
로컬 개발 및 테스트를 위한 Vercel REST API 에뮬레이션입니다. 사용자가 로컬에서 Vercel API 엔드포인트와 상호작용하거나 Vercel 통합을 테스트해야 할 때 사용합니다.
cron-jobs
vercel
Vercel Cron Jobs 구성 및 모범 사례. vercel.json에서 예약된 작업을 추가, 편집 또는 디버깅할 때 사용합니다.
codegen
vercel
json-render을 위한 코드 생성 유틸리티입니다. UI 명세서에서 코드를 생성하거나, 사용자 정의 코드 내보내기를 구축하거나, 명세서를 탐색하거나, props를 직렬화할 때 사용합니다.
next-best-practice
vercel
Next.js 모범 사례 - 파일 규칙, RSC 경계, 데이터 패턴, 비동기 API, 메타데이터, 오류 처리, 라우트 핸들러, 이미지/폰트 최적화,…
benchmark-sandbox
vercel
Vercel Sandbox에서 vercel-plugin eval 시나리오를 로컬 WezTerm 패널 대신 실행합니다. Claude Code와 플러그인이 사전 설치된 임시 마이크로VM을 프로비저닝합니다.
write-guide
vercel
점진적인 예제를 통해 실제 사용 사례를 가르치는 기술 가이드를 제작합니다. 개념은 독자가 필요로 할 때만 소개됩니다.
benchmark-testing
vercel
벤치마크 테스트 프로젝트를 생성하고 실행하여 실제 시나리오에서 vercel-plugin 스킬 인젝션을 테스트합니다. 격리된 디렉토리를 설정하고, 설치하며…
ai-gateway
vercel
Vercel AI Gateway 전문가 안내. 모델 라우팅, 제공업체 장애 조치, 비용 추적 또는 통합된 방식을 통해 여러 AI 제공업체를 관리할 때 사용합니다.