1.问题描述:对两个文件的文本进行差异比对,文件大小为:小于5M。

2.前端组件调研:

①vue-code-diff:优点:该组件可一次渲染所有差异(差异行有红色和绿色的背景色),差异一目了然。缺点:文本量大时,例如10000行,页面直接崩溃,所以该组件不适合数据量大的文本。不符合要求。

②vue-codemirror :优点:vue-codemirror搭配diff-match-patch可进行大数据量的文本比对(几百万行也不在话下)。缺点:滚动渲染,不会一次渲染所有差异,而是滚动到哪里,稍停片刻,或者缓慢滚动,才会看到差异(差异行有淡黄色背景色,差异文字有红色和绿色波浪线)。所以,拖动滚动条过快时,可能差异还没渲染出来,就已经滚动过去了,不能一目了然的知道有几处差异。

3.解决方案:鉴于vue-code-diff对大数据量不不友好,直接pass掉。选用vue-codemirror搭配diff-match-patch。为了改善“滚动渲染,不会一次渲染所有差异,不能一目了然的知道有几处差异”的缺点,增加文字描述,示例如下:共4处差异,每处差异的开始行号为:2、589、2904、12328。这样用户可拖动滚动条到这些行,当滚动停止时,差异渲染出来,可看到这些行的具体差异。

4.实现效果:

使用codeMorror进行文本比对

使用codeMirror实现文本比对

5.实现步骤如下:

(1)安装插件

npm install vue-codemirror@4.0.6 -S
npm install diff-match-patch -S

(2)导入包

import { codemirror } from "vue-codemirror";
require("codemirror/mode/javascript/javascript.js");
import CodeMirror from "codemirror";
import "codemirror/lib/codemirror.css";
import "codemirror/addon/merge/merge.js"
import "codemirror/addon/merge/merge.css"
import DiffMatchPatch from "diff-match-patch";
window.diff_match_patch = DiffMatchPatch;
window.DIFF_DELETE = -1;
window.DIFF_INSERT = 1;
window.DIFF_EQUAL = 0;

(3)template中

<div>
  <div>{{ diffDescription }}</div>
  <div ref="contrastDiv"></div>
</div>

(4)script中

  data() {
    return {
      leftText: "", //左侧展示文本
      rightText: "", //右侧展示文本
      diffDescription: "", //差异内容描述
    };
  },
  mounted() {
    this.prepareData()
    this.contrast();
  },
  methods: {
    prepareData(){
      for(let i=0;i<10;i++){
        this.leftText+='a\n'
        this.rightText+='b\n'
      }
      for(let i=0;i<100;i++){
        this.leftText+='a\n'
        this.rightText+='a\n'
      }
      for(let i=0;i<10;i++){
        this.leftText+='abbbbbbbbbbfadsfasfasfasfasfadsfadsfds\n'
        this.rightText+='bweefdrrsxsssffasfsadfadsfadsfadsfasdfa\n'
      }
      for(let i=0;i<10000;i++){
        this.leftText+='bbb\n'
        this.rightText+='bbb\n'
      }
      for(let i=0;i<10;i++){
        this.leftText+='a\n'
        this.rightText+='b\n'
      }
    },
    contrast() {
      this.$nextTick(() => {
        const target = this.$refs.contrastDiv;
        target.innerHTML = "";
        let difference = CodeMirror.MergeView(target, {
          value: this.leftText,
          originLeft: null,
          orig: this.rightText,
          lineNumbers: true,
          mode: "text/html",
          hightlightDifference: true,
          connect: "align",
          readOnly: true,
          theme: "dracula",
          smartIndent: true,
        });
        let diffCount = difference.right.chunks.length;
        console.log(diffCount)
        let description = "";
        if (diffCount === 0) {
          description = "左右文本内容一致";
        } else if (diffCount === 1) {
          description =
            "共1处差异,差异的开始行号为:" +
            (difference.right.chunks[0].origFrom + 1);
        } else {
          description = "共" + diffCount + "处差异,每处差异的开始行号为:";
          for (let i = 0; i < diffCount; i++) {
            description += difference.right.chunks[i].origFrom + 1;
            if (i !== diffCount - 1) {
              description += "、";
            }
          }
        }
        this.diffDescription=description

      });
    },
  },

有需要的小伙伴快去试试吧! 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐