文本 diff 类似 git 显示

需求:

  • 两个文本进行比对差异
  • 比对结果像git change 一样展示
  • 自由限定文本间的差异

进程:

  • 查找到相应的控件
  • diff  diff2html
  • npm install diff     npm install diff2html
  • diff 可以对比两个文本, diff2html  可以将对比结果渲染成html
  • import { createPatch } from "diff";

    diff 还有其他的方法,diffWords, diffjson 等,不过返回的格式是一个正常的json,并不是patch

  • diff 参考https://juejin.cn/post/6855129008007774216

  • import { html, parse } from "diff2html";
    import "diff2html/bundles/css/diff2html.min.css";
    import { Diff2HtmlUI } from "diff2html/lib/ui/js/diff2html-ui"; 

    diff2html 需要引用自带的css

  • diff2html 参考https://github.com/rtfpessoa/diff2html#usage

  • parse 可以将diff 出来的patch 转换成自己可用的格式

  • html 可以将parse 出来的json 展示成对应的html

  • let oldString = JSON.stringify(oldContent, null, 2);
    let newString = JSON.stringify(newContent, null, 2);
    
    let args = [ "", oldString, newString, "", "", { context: moreLine } ];
    const diffStr = createPatch(...args);
    
    const diffJson = parse(diffStr);
    const diffHtml = html(diffJsonList, {
              drawFileList: true, matching: "lines", showFiles: false, outputFormat: "side-by-side"
    });
    

    最后只要再做一次渲染就可以了

  • 如果使用Diff2HtmlUI  相对于 html 他有更多的功能

  • let oldString = JSON.stringify(oldContent, null, 2);
    let newString = JSON.stringify(newContent, null, 2);
    
    let args = [ "", oldString, newString, "", "", { context: moreLine } ];
    const diffStr = createPatch(...args);
    
    const diffJson = parse(diffStr);
    
    const targetElement = document.getElementById(id);
    
    const diff2htmlUi = new Diff2HtmlUI(targetElement, diffJsonList, {
              drawFileList: true, matching: "lines", showFiles: false, outputFormat: "side-by-side"
    });
    
    diff2htmlUi.draw();		//绘制页面
    diff2htmlUi.highlightCode();	// 高亮数据
    diff2htmlUi.fileListToggle(fileListToggle);

  • <div dangerouslySetInnerHTML={{__html: diffHtml }}/>

结果展示: 

完整的代码块 :

import React, {useEffect, useState} from 'react';
import { createPatch } from "diff";
import { html, parse } from "diff2html";
import "diff2html/bundles/css/diff2html.min.css";
import "./index.less"

export type ContentDiffProps = {
  oldContent: string;
  newContent: string;
  moreLine: number;
}

const ContentDiff: React.FC<ContentDiffProps> = (props) => {
  const [ diffData, setDiffData ] = useState("");
  const diffJsonList = [];
  const {oldContent, newContent, moreLine} = props;

  useEffect(() => {
    createDiffData();
  }, [oldContent, newContent, moreLine]);

  const createDiffData = () => {
    let oldString = JSON.stringify(oldContent, null, 2);
    let newString = JSON.stringify(newContent, null, 2);

    let args = [ "", oldString, newString, "", "", { context: moreLine } ];
    const diffStr = createPatch(...args);

    // 差异json化
    const diffJson = parse(diffStr);
    diffJsonList.push(diffJson[0]);

    const diffHtml = html(diffJsonList, {
      drawFileList: true, matching: "lines", showFiles: false, outputFormat: "side-by-side"
    });
    setDiffData(diffHtml);
  }

  return (
    <div dangerouslySetInnerHTML={{__html: diffData}}/>
  )
}

export default ContentDiff;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值