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(绝对值)。单目运算(round、floor、ceil、abs)仅读取参数 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 |
国际化配置项的类型定义 |






