json 對比工具-react

564 阅读1分钟

jsdiff 的使用

简介

jsdiff 是一个可以对json,字符串进行比较的插件,是一个基于javascript实现的文本内容diff的库(目前最高适配到react18,此文章主要讲json的对比)

1. 下载与引入

git : github.com/kpdecker/js…

npm : www.npmjs.com/package/dif…

npm i diff
const Diff = require('diff');

2. 使用

const a = [  {    aa: [      "5",      [65, [88]],
    ],
  },
  {
    ddd: 879,
  },
];

const b = [  { aa: [55, [65, [88, [55]]]] },
  { aaa: [67] },
  {
    ddd: 88,
    bbc: 666,
  },
];
const diffstr = jsdiff.diffJson(a, b);

3. 结果

[
    // 无变化
    {
        "count": 3,
        "value": "[\n  {\n    \"aa\": [\n"
    },
    // 删除
    {
        "count": 1,
        "removed": true,
        "value": "      \"5\",\n"
    },
    // 新增
    {
        "count": 1,
        "added": true,
        "value": "      55,\n"
    },
   .....
]

4. 根据返回结果,使用antd的界面效果

1670989101(1).png

5. Demo代码

import { Col, Row } from "antd";
const jsdiff = require("diff");

const a = [
  {
    aa: [
      "5",
      [65, [88]],
    ],
  },
  {
    ddd: 879,
  },
];

const b = [
  { aa: [55, [65, [88, [55]]]] },
  { aaa: [67] },
  {
    ddd: 88,
    bbc: 666,
  },
];
const diffstr = jsdiff.diffJson(a, b);

const ColumnContext = ({ str, color }) => {
  let count = 0;

  return (
    <Col span={12} style={{ padding: 15 }}>
      {diffstr.map((item) => {
        const have = str === "removed" ? item.removed : item.added;
        if (have || (!item.removed && !item.added)) {
         // 处理含有\n的字符串,进行换行
          return (
            <>
              {item.value.split("\n").map((child) => {
                if (child) {
                  count = count + 1;
                }
                return (
                  child && (
                    <Row style={{ background: have && color }}>
                      <Col
                        className={have ? "unselect" : "unselect count"}
                        style={{
                          background: have ? color : "#f7f7f7",
                        }}
                      >
                        <pre
                          style={{
                            padding: 5,
                            margin: 0,

                            width: "40px",
                            textAlign: "right",
                          }}
                        >
                          {count}
                        </pre>
                      </Col>
                      <Col>
                        <pre
                          className="unselect"
                          style={{
                            background: have && color,
                            padding: 5,
                            margin: 0,
                            opacity: have ? 1 : 0,
                            heigt: "100%",
                          }}
                        >
                          {str === "removed" ? "-" : "+"}
                        </pre>
                      </Col>
                      <Col style={{ width: "calc(100% - 80px)" }}>
                        <pre
                          style={{
                            padding: 5,
                            margin: 0,
                            whiteSpace: "pre-wrap",
                            wordWrap: "break-word",
                          }}
                        >
                          {child}
                        </pre>
                      </Col>
                    </Row>
                  )
                );
              })}
            </>
          );
        }
        // 控制空白行
        return (
          <div>
            {item.value.split("\n").map((child) => {
              return (
                child && (
                  <Row style={{ background: have && color }}>
                    <Col
                      className="unselect"
                      style={{
                        background: "#f7f7f7",
                      }}
                    >
                      <pre
                        style={{
                          padding: 5,
                          margin: 0,
                          heigt: "100%",
                          width: "40px",
                          textAlign: "right",
                        }}
                      />
                    </Col>
                    <Col className="unselect">
                      <pre
                        className="unselect"
                        style={{
                          background: have && color,
                          padding: 5,
                          margin: 0,
                          opacity: 0,
                          heigt: "100%",
                        }}
                      >
                        -
                      </pre>
                    </Col>
                  </Row>
                )
              );
            })}
          </div>
        );
      })}
    </Col>
  );
};

const DiffCom = () => {
  return (
    <Row style={{ textAlign: "left", margin: 15 }}>
      <ColumnContext str="removed" color="#fdb8c0" />
      <ColumnContext str="added" color="#acf2db" />
    </Row>
  );
};
export default DiffCom;