赞
踩
安装 react-json-view:npm install --save react-json-view
可参考的一些开源库:react-json-path-picker,json-path-picker
线上工具:jsonpath tool
用来解析多层嵌套的json数据。JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Python, PHP 和 Java。
本质: 通过一种语法规则快速从 JSON 数据中提取数据。类似于 正则表达式 通过一定规则从 text 文本内容提取数据。
语法规则:
参考文档:JSON 数据提取
import ReactJson from 'react-json-view'; interface Props { jsonValue: any; updateJsonPath: (value: string) => void; } export function JsonPathFilter(props: Props) { const { jsonValue, updateJsonPath } = props; const getValue = (select: any) => { const { name, namespace } = select; namespace.push(name); const reg = /^[0-9]*$/g; let path = ''; namespace.forEach((s: string) => { if (reg.test(s)) { path = path?.substring(0, path.length - 1); path = `${path}[${s}].`; } else { path = `${path + s}.`; } }); path = path?.substring(0, path.length - 1); return path; }; return <ReactJson src={jsonValue} onSelect={(select) => updateJsonPath(getValue(select))} />; }
select
数据类型:
效果图:
考虑到上述方案只能通过点击叶子结点的value来获取path,如果说我们点击任意节点的key或者value都可以获取到path的话,上述方案就不太可行,react-json-view
开源库不提供对任意节点点击的监听事件。
调研发现,我们可以使用jsoneditor,注意官方给定的onSelectionChang
方法,是针对选择多行(或者一行)时,起始节点数据,比如下图所示,选择的是一个区间。这种用法并不太符合我们的要求,我们希望的是对节点的点击事件进行监听。
查看文档,找到了onEvent
方法,可以对节点的key和value进行事件监听,包括鼠标移入移除,点击,聚焦等事件。
这里,我们需要监听的是点击事件。
首先,我们先封装一下JsonEditor,代码如下,
JsonEditor/index.tsx:
import { useMemoizedFn } from 'ahooks'; import JSONEditor from 'jsoneditor'; import { useEffect, useState } from 'react'; import './index.less'; interface Props { jsonValue: any; otherOpts?: any; domId?: string; isExpandAll?: boolean; containerStyle?: any; } export default function JsonEditor(props: Props) { const { jsonValue, otherOpts = {}, domId = 'jsoneditor', isExpandAll, containerStyle } = props; const [jsonRef, setJsonRef] = useState<any>(null); let editor: any; const renderJsonEditor = useMemoizedFn(() => { const container = document.getElementById(domId); if (container) { container.innerHTML = ''; // 防止添加多个jsoneditor const options: any = { mode: 'view', modes: ['code', 'text', 'tree', 'view'], language: 'en', ...otherOpts, }; editor = new JSONEditor(container, options); editor.set(jsonValue); if (isExpandAll) { editor.expandAll(); } } }); useEffect(() => { renderJsonEditor(); return () => { editor?.destroy(); }; }, [jsonRef, renderJsonEditor, jsonValue, editor]); return <div style={containerStyle} ref={setJsonRef} id={domId} />; }
JsonEditor/index.less:
div.jsoneditor-field,
div.jsoneditor-value {
cursor: pointer;
}
调整后的JsonPathFilter代码如下,
JsonPathFilter/index.tsx:
import JsonEditor from '../JsonEditor'; interface Props { jsonValue: any; updateJsonPath: (value: string) => void; domId: string; } export function JsonPathFilter(props: Props) { const { jsonValue, updateJsonPath, domId } = props; const getValue = (namespace: any) => { let path = ''; namespace?.forEach((s: string | number) => { if (typeof s === 'number') { path = path?.substring(0, path.length - 1); path = `${path}[${s}].`; } else { path = `${path + s}.`; } }); path = path?.substring(0, path.length - 1); return path; }; return ( <JsonEditor jsonValue={jsonValue} domId={domId} otherOpts={{ onEvent: (item: any, event: any) => { if (event.type === 'click') { // 判断事件类型 // 监听点击 key 或者 value 的时候 updateJsonPath(getValue(item.path)); } }, }} /> ); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。