directives

directives

热门

json-render 的开箱即用自定义指令集,涵盖格式化、数学计算、字符串处理及国际化(i18n)。适用于使用 @json-render/directives、通过 defineDirective 自定义指令,或在 spec 中添加 $format、$math、$concat、$count、$truncate、$pluralize、$join、$t 等指令的场景。

1.6万Star
853Fork
更新于 2026/7/8
SKILL.md
只读
名称
directives
描述

json-render 的开箱即用自定义指令集,涵盖格式化、数学计算、字符串处理及国际化(i18n)。适用于使用 @json-render/directives、通过 defineDirective 自定义指令,或在 spec 中添加 $format、$math、$concat、$count、$truncate、$pluralize、$join、$t 等指令的场景。

@json-render/directives

专为 @json-render/core 打造的预置自定义指令集。直接接入你的 catalog 和渲染器,即可快速扩展格式化、算术运算、字符串操作以及国际化(i18n)功能。

快速上手

import { standardDirectives } from '@json-render/directives';

// 接入 Prompt 生成逻辑
const prompt = catalog.prompt({ directives: standardDirectives });

// 接入渲染器(以 React 为例)
import { JSONUIProvider, Renderer } from '@json-render/react';

<JSONUIProvider registry={registry} directives={standardDirectives}>
  <Renderer spec={spec} registry={registry} />
</JSONUIProvider>

若需添加 createI18nDirective 等工厂函数生成的指令,直接展开数组即可:

import { standardDirectives, createI18nDirective } from '@json-render/directives';

const directives = [...standardDirectives, createI18nDirective(config)];

定义自定义指令

使用 @json-render/core 中的 defineDirective

import { defineDirective, resolvePropValue } from '@json-render/core';
import { z } from 'zod';

const doubleDirective = defineDirective({
  name: '$double',
  description: 'Double a numeric value.',
  schema: z.object({
    $double: z.unknown(),
  }),
  resolve(value, ctx) {
    const resolved = resolvePropValue(value.$double, ctx);
    return (resolved as number) * 2;
  },
});

规则:

  • 指令名称必须以 $ 开头
  • 名称不能与内置 Key 冲突($state$cond$computed$template$item$index$bindState$bindItem
  • Resolver 内部应当对子值调用 resolvePropValue,以支持指令组合嵌套

内置指令

$format — 适配 Locale 的格式化

基于 Intl 格式化工具对值进行处理。支持 date(日期)、currency(货币)、number(数字)及 percent(百分比)。

{ "$format": "currency", "value": { "$state": "/cart/total" }, "currency": "USD" }
{ "$format": "date", "value": { "$state": "/user/createdAt" } }
{ "$format": "number", "value": 1234567, "notation": "compact" }
{ "$format": "percent", "value": 0.75 }
{ "$format": "date", "value": { "$state": "/post/createdAt" }, "style": "relative" }

字段说明:$format(date | currency | number | percent)、value(任意表达式)、locale?(字符串)、currency?(字符串,默认为 "USD")、notation?(字符串)、style?(相对日期传入 "relative")、options?(Intl 的额外配置项)。

$math — 算术运算

{ "$math": "add", "a": { "$state": "/subtotal" }, "b": { "$state": "/tax" } }
{ "$math": "round", "a": 3.7 }

支持的操作:add(加)、subtract(减)、multiply(乘)、divide(除)、mod(取模)、min(最小值)、max(最大值)、round(四舍五入)、floor(向下取整)、ceil(向上取整)、abs(绝对值)。单目运算(roundfloorceilabs)仅读取参数 a。除以 0 时返回 0

字段说明:$math(运算操作枚举)、a?(第一个操作数,默认为 0)、b?(第二个操作数,默认为 0)。

$concat — 字符串拼接

{ "$concat": [{ "$state": "/user/firstName" }, " ", { "$state": "/user/lastName" }] }

字段说明:$concat(待解析并拼接为字符串的值数组)。

$count — 数组/字符串长度获取

{ "$count": { "$state": "/cart/items" } }

返回数组或字符串的 .length,其他类型返回 0

字段说明:$count(待计算长度的值)。

$truncate — 文本截断

{ "$truncate": { "$state": "/post/body" }, "length": 140, "suffix": "..." }

字段说明:$truncate(待截断的值)、length?(最大字符数,默认为 100)、suffix?(后缀字符串,默认为 "...")。

$pluralize — 单复数形式转换

{ "$pluralize": { "$state": "/cart/itemCount" }, "one": "item", "other": "items", "zero": "no items" }

输出示例:"3 items""1 item""no items"

字段说明:$pluralize(计数数值)、one(单数文案)、other(复数文案)、zero?(为 0 时的文案)。

$join — 数组元素连接

{ "$join": { "$state": "/tags" }, "separator": ", " }

字段说明:$join(待连接的数组)、separator?(分隔符字符串,默认为 ", ")。

createI18nDirective — 国际化指令工厂函数

import { createI18nDirective } from '@json-render/directives';

const tDirective = createI18nDirective({
  locale: 'en',
  messages: {
    en: { "greeting": "Hello, {{name}}!", "checkout.submit": "Place Order" },
    es: { "greeting": "Hola, {{name}}!", "checkout.submit": "Realizar Pedido" },
  },
  fallbackLocale: 'en',
});

在 spec 中的用法:

{ "$t": "checkout.submit" }
{ "$t": "greeting", "params": { "name": { "$state": "/user/name" } } }

字段说明:$t(翻译 Key)、params?(插值参数,属性值支持传入表达式)。

配置说明:locale(当前语言环境)、messages(字典对象,格式为 Record<locale, Record<key, string>>)、fallbackLocale?(Key 缺失时的降级语言环境)。

指令组合(Composition)

指令天然支持组合使用 — 每一个 Resolver 在处理输入时都会调用 resolvePropValue,因此指令可以轻松包裹其他指令或内置表达式:

{
  "$format": "currency",
  "value": { "$math": "multiply", "a": { "$state": "/price" }, "b": { "$state": "/qty" } },
  "currency": "USD"
}

解析顺序由内而外:$state 获取状态数据,$math 计算乘积,$format 将结果格式化为货币。

接入渲染器

所有四种渲染器(React、Vue、Svelte、Solid)的 Provider 以及 createRenderer 输出均支持传入 directives

// Provider 模式
<JSONUIProvider registry={registry} directives={directives}>
  <Renderer spec={spec} registry={registry} />
</JSONUIProvider>

// createRenderer 模式
const MyRenderer = createRenderer(catalog, components);
<MyRenderer spec={spec} directives={directives} />

生成 Prompt 时传入相同的数组即可:

const prompt = catalog.prompt({ directives });

核心导出(Key Exports)

导出名称 用途
formatDirective $format 指令定义
mathDirective $math 指令定义
concatDirective $concat 指令定义
countDirective $count 指令定义
truncateDirective $truncate 指令定义
pluralizeDirective $pluralize 指令定义
joinDirective $join 指令定义
createI18nDirective 创建 $t 国际化指令的工厂函数
standardDirectives 包含所有 7 个非工厂指令的数组
I18nConfig 国际化配置项的类型定义