使用场景
JsonViewer 组件可用于 JSON 数据的展示与编辑。底层参考了 VS Code 的 text-buffer 数据结构设计思路,结合功能/样式定制需求实现,视觉上与设计体系内其他组件更协调,对特定数据类型的定制化渲染更方便。相比直接使用 MonacoEditor,JsonViewer 仅关注 JSON 数据格式,更轻量、加载更快、内存占用更少,开箱即用无需关注复杂的构建配置。
- 如果你仅需要对 JSON 做预览/编辑,无需对更复杂的其他编程语言作修改,建议选用 JsonViewer。
- 如果你还需要处理其他格式的数据/代码文件,完整的代码编辑器能力(语法高亮、代码补全、错误提示、复杂编辑等)是刚需,构建产物体积不是关注重点,建议选用 Monaco Editor。
代码演示
如何引入
import { JsonViewer } from '@chenzy-design/svelte'; 基本用法
JsonViewer 的基本用法。传入 height 和 width 参数设置组件的高度和宽度,通过 value 传入 JSON 字符串。
JsonViewer 为非受控组件,value 仅用于初始化。若需获取组件的值,可通过 bind:this 拿到实例后调用方法,具体参考 Methods;不建议在 onChange 中反过来修改传入的 value,因为外部主动传入新的 value 会重建整个编辑器实例(丢失光标位置、折叠状态等)。
只读模式
配置 options 的 readOnly 参数为 true 时,内容不可编辑,仅用于展示(此时搜索/替换工具条中的替换栏也不会渲染)。
设置行高
配置 options 的 lineHeight 参数,设置固定行高(单位:px,默认 18)。
自动换行
配置 options 的 autoWrap 参数,设置为 true 时,组件会根据内容长度自动换行。
格式化配置
配置 options 的 formatOptions 参数,设置组件的格式化配置。
tabSize:number,设置缩进大小为 4,表示每级缩进 4 个空格insertSpaces:boolean,true表示使用空格进行缩进,false表示使用制表符(Tab)eol:string,设置换行符,可以是\n、\r\n
自定义渲染规则
通过配置 options.customRenderRule 参数,你可以自定义 JSON 内容的渲染方式(注意:仅在只读模式下生效)。
Semi 的 render 返回 React 节点;本库 core 契约要求 render 返回 HTMLElement。因此本库示例用 Svelte 的命令式 mount() 把真实组件(Popover / Rating / Tag / Image)挂到返回的 DOM 上,视觉与交互与 Semi 等效。
从 2.96.0 起,customRenderRule 在计算 path 时会更精确:同一条键值对的 key token 与 value token 会拥有相同的 path(即都对应到该属性所在的路径,例如 root.<key>)。
因此,像 path === 'root.<key>' 这类仅依赖 path 的规则,可能同时命中 key 和 value,导致与后续 value 匹配规则产生”覆盖/优先级”差异。
若你希望只匹配 key 或只匹配 value,请使用函数匹配的第三个参数 tokenType:
const targetPath = 'root.<key>';
// 仅匹配 key
match: (_value, path, tokenType) => tokenType === 'key' && path === targetPath;
// 仅匹配 value
match: (value, path, tokenType) => tokenType === 'value' && path === targetPath;customRenderRule 是一个规则数组,每条规则包含两个属性:
match:匹配条件,可以是以下三种类型之一:- 字符串:精确匹配
- 正则表达式:按正则匹配
- 函数:自定义匹配逻辑,函数签名为
(value, path, tokenType) => booleanvalue:待匹配的值(JSON 键或值)。当match为函数时,value会尽量传入解析后的原始类型(number / boolean / null / string),因此可以使用===进行严格匹配;当match为字符串或正则时,仍基于文本内容匹配(字符串类型会去除两侧引号)path:当前匹配到的路径,格式为root.key1.key2.key3[0].key4tokenType:当前 token 的类型,'key'表示 JSON 键名,'value'表示 JSON 值,可用于区分同名键和值的匹配
render:自定义渲染函数,函数签名为(content: string) => HTMLElementcontent:匹配到的内容。如果是字符串类型的值,将包含双引号(如"name"、"Semi")
自定义搜索按钮
通过 renderSearchButton 属性,你可以自定义搜索按钮的渲染方式,实现固定位置、自定义样式等需求。
API 参考
JsonViewer
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| value | 展示内容 | string | - |
| height | 高度 | number | string | - |
| width | 宽度 | number | string | - |
| class | 类名 | string | - |
| style | 内联样式 | string | - |
| showSearch | 是否显示搜索 Icon | boolean | true |
| limitSearchButtonBounds | 是否限制搜索按钮拖动范围在容器内 | boolean | false |
| renderSearchButton | 自定义渲染搜索按钮 | Snippet<[Snippet, SearchControls]> | - |
| options | 编辑器配置 | JsonViewerOptions | - |
| onChange | 内容变化回调 | (value: string) => void | - |
| onCustomRender | 只读模式命中 customRenderRule 时透出 customRenderMap | (map: Map<HTMLElement, unknown>) => void | - |
| renderTooltip | 自定义 hover 提示内容 | (value: string, el: HTMLElement) => HTMLElement | - |
JsonViewerOptions
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| lineHeight | 行高 | number | 20 |
| autoWrap | 是否自动换行 | boolean | true |
| readOnly | 是否只读 | boolean | false |
| customRenderRule | 自定义渲染规则 | CustomRenderRule[] | - |
| formatOptions | 格式化配置 | FormattingOptions | - |
CustomRenderRule
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| match | 匹配规则 | string \| RegExp \| (value, path, tokenType) => boolean | - |
| render | 渲染函数 | (content: string) => HTMLElement | - |
FormattingOptions
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| tabSize | 缩进大小 | number | 4 |
| insertSpaces | 是否使用空格进行缩进 | boolean | true |
| eol | 换行符 | string | \n |
SearchControls
当使用 renderSearchButton 时,第二个参数 controls 包含以下属性:
| 属性 | 说明 | 类型 |
|---|---|---|
| showSearchBar | 当前是否显示搜索栏 | boolean |
| onToggleSearchBar | 切换搜索栏显示/隐藏 | () => void |
| onSearch | 执行搜索 | (text: string, caseSensitive?: boolean, wholeWord?: boolean, regex?: boolean) => void |
| onPrevSearch | 跳转到上一个搜索结果 | () => void |
| onNextSearch | 跳转到下一个搜索结果 | () => void |
| onReplace | 替换当前搜索结果 | (text: string) => void |
| onReplaceAll | 替换所有搜索结果 | (text: string) => void |
Methods
可以通过 bind:this 拿到组件实例,调用其上绑定的方法,实现某些特殊交互。
| 名称 | 描述 |
|---|---|
| getValue() | 获取当前值 |
| format() | 格式化当前内容 |
| search(searchText, caseSensitive?, wholeWord?, regex?) | 搜索文本,可选参数控制大小写敏感、全词匹配和正则表达式 |
| getSearchResults() | 获取当前搜索结果 |
| prevSearch(step?) | 导航到上一个搜索结果,可选步长参数 |
| nextSearch(step?) | 导航到下一个搜索结果,可选步长参数 |
| replace(replaceText) | 替换当前搜索匹配项 |
| replaceAll(replaceText) | 替换所有搜索匹配项 |
设计变量
变量 | 默认值 | 用法 |
|---|---|---|
| --cd-color-json-viewer-bg | var(--cd-color-default) | 编辑器容器背景(Semi $color-json-viewer-background = var(--semi-color-default)) |
| --cd-color-json-viewer-bracket-0 | var(--cd-color-blue-7) | delimiter-bracket-0/array-0(对齐 Semi blue-7) |
| --cd-color-json-viewer-bracket-1 | var(--cd-color-green-7) | delimiter-bracket-1/array-1(对齐 Semi green-7) |
| --cd-color-json-viewer-bracket-2 | var(--cd-color-orange-7) | delimiter-bracket-2/array-2(对齐 Semi orange-7) |
| --cd-color-json-viewer-comment | var(--cd-color-text-3) | comment-*:JSONC 注释(Semi 无此 token,取中性灰) |
| --cd-color-json-viewer-complete-bg | var(--cd-color-bg-3) | complete-suggestions-container 背景(对齐 Semi bg-3) |
| --cd-color-json-viewer-error | var(--cd-color-danger) | error:语法错误波浪线色 |
| --cd-color-json-viewer-folding-icon | var(--cd-color-blue-7) | folding-icon:折叠图标色(对齐 Semi blue-7) |
| --cd-color-json-viewer-key | var(--cd-color-red-5) | string-key:对象键名(对齐 Semi red-5) |
| --cd-color-json-viewer-keyword | var(--cd-color-blue-5) | keyword:布尔与 null(对齐 Semi blue-5) |
- 1
- 2
- 3