前端通过 jsDiff + diff2html实现数据(代码)比较

背景

在最近的开发过程需要实现两条数据的对比效果,方便客户使用,看了一下市场上有比较不少完整的插件,就选择了其中一种来实现

技术选型

插件: jsDiff + diff2html

框架:vue3+elementplus

实现功能及效果图:

通过点击事件实现弹框展示两条数据对比

1.下载相关依赖

yarn add diff
yarn add diff2html
yarn add @types/diff

2.html部分

<template>
  <el-button plain @click="openDiff"> Click to open the diffDialog </el-button>

  <el-dialog
    v-model="dialogVisible"
    title="Tips"
    width="900"
    :before-close="handleClose"
  >
    <div ref="diffContainer"></div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="dialogVisible = false">
          Confirm
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

3.js实现部分

注意:在弹框中展示需要nextTick回调等弹框渲染完毕后再获取节点,在执行draw方法渲染

<script setup lang="ts">
import { ElDialog, ElButton } from "element-plus";
import { ref, nextTick } from "vue";
import { createTwoFilesPatch } from "diff";
import { Diff2HtmlUI } from "diff2html/lib/ui/js/diff2html-ui";
import "highlight.js/styles/googlecode.css";
import "diff2html/bundles/css/diff2html.min.css";

const dialogVisible = ref(false);

const handleClose = () => {};

// 差异字符串(通常通过diff算法生成)
// 定义两个JSON对象(作为示例)
const obj1 = { a: "牛魔王", b: 2, c: { d: 3 } };
const obj2 = { a: "胡图图", b: 3, c: { d: 4 } };

// 将JSON对象转换为字符串进行比较
const text1 = JSON.stringify(obj1, null, 2);
const text2 = JSON.stringify(obj2, null, 2);

const diffContainer = ref<HTMLElement | null>(null);

let configuration = {
  drawFileList: true, // 是否在差异之前显示文件列表
  fileListToggle: false, // 是否允许切换文件列表的显示
  fileListStartVisible: false, // 文件列表是否初始时可见
  matching: "lines", // 匹配级别:行
  outputFormat: "side-by-side", // 输出格式:并排显示
  synchronizedScroll: true, // 同步滚动(并排模式)
  highlight: true, // 是否高亮显示代码
  renderNothingWhenEmpty: false, // 如果没有差异,是否渲染空内容
};

//diff代码比对
const openDiff = () => {
  dialogVisible.value = true;
  const diffOutput = createTwoFilesPatch(
    "text1.json",
    "text2.json",
    text1,
    text2
  );
  console.log(diffOutput);

  // 初始化diff2htmlUI并配置
  // 创建并绘制diff
  //dom更新之后再执行比较,否则查询不到dom节点 直接报错
  nextTick(() => {
    if (diffContainer.value) {
      let diff2htmlUi = new Diff2HtmlUI(
        diffContainer.value, //渲染节点
        diffOutput, //内容
        configuration //配置项
      );
      diff2htmlUi.draw();
      diff2htmlUi.highlightCode();
    }
  });
};
</script>

效果图如下

补充

在弹框中如果数据过多,可能导致右侧序号不滚动,左侧代码内容滚动问题 是因为 .d2h-code-side-linenumber 样式设置了绝对定位导致。

样式错乱图如下  左侧序号跟右侧代码内容不对照

解决思路

:deep(.d2h-code-side-linenumber) {
  position: relative;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值