当前位置:   article > 正文

react实现点击获取json对象的jsonPath_react 获取本地json文件内容

react 获取本地json文件内容

准备

安装 react-json-viewnpm install --save react-json-view

可参考的一些开源库:react-json-path-pickerjson-path-picker
线上工具:jsonpath tool

JsonPath

JsonPath官方文档

用来解析多层嵌套的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))} />;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

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} />;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

JsonEditor/index.less:

div.jsoneditor-field,
div.jsoneditor-value {
  cursor: pointer;
}

  • 1
  • 2
  • 3
  • 4
  • 5

调整后的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));
          }
        },
      }}
    />
  );
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/977890
推荐阅读
相关标签
  

闽ICP备14008679号