美文网首页
json对比,并标红差异部分

json对比,并标红差异部分

作者: 菜蚴菜 | 来源:发表于2021-11-11 17:55 被阅读0次
一、安装引入依赖

安装依赖

npm install diff --save

引用依赖

//  不支持import 语法,也就是module引入
const jsDiff = require('diff');

这里不对diff库的详细内容做说明,具体可参考:https://www.npmjs.com/package/diff
本文只针对对比两个json,并标红差异部分的实现做说明

二、代码实现
//在页面中获取对比后的结果
   // 当前json
   let content ={
          name:'john',
          list:{
            hobby:'篮球'
          },
          content:'我是单独的一段文字',
          result:'结果是好的'
       }
    //历史json
    let oldContent = {
          name:'tom',
          list:{
            hobby:'足球'
          }, 
          result:'结果是坏的'
      }
  //获取对比结果
  let {  addedHtml ,  removedHtml  } = diffHistory(content ,oldContent )

 //使用的时候
 <div v-html="addedHtml"></div>
 <div v-html="removedHtml "></div>
   //获取对比后的结果及拼接展示效果
   diffHistory() {
        // diff之后的结果
        var diffResult = jsDiff.diffJson(oldContent, content)
        let addedList = []
        let removedList = []
        //遍历对比结果,摘出相应的数据
        //首先判断的量级为一行
        diffResult.forEach((diffObj, index) => {
          let content = diffObj.value
          let replaceContent = this.replaceContent(content)
          //该项的下一项
          let next = diffResult[index + 1]
          let nextReplceContent = next && this.replaceContent(next.value)
          if (diffObj.removed) {
            //需要展示在历史结果位置的数据
            let dealedContent = ''
            if (diffObj.removeContent) {
              dealedContent = diffObj.removeContent
            } else {
              //判断下一个项
              if (next && next.added) {
                //说明两个项之前是对应的关系
                //判断在不同的这行中,具体到字段的不同位置
                let testDiffList = jsDiff.diffWordsWithSpace(
                  replaceContent,
                  nextReplceContent
                )
                let { addContent, removeContent } = this.diffText(testDiffList)
                next.addContent = addContent
                dealedContent = removeContent
              } else {
               //如果想用空白,对没有内容的地方占位 start
               addedList.push('<span  style="visibility:hidden;">' + replaceContent +'</span>')
               //如果想用空白,对没有内容的地方占位 end
                dealedContent =
                  '<span style="color:red"">' +
                   replaceContent.replace(/\s/gm, '&ensp;')+
                  '</span>'
              }
              removedList.push(dealedContent)
            }
          } else if (diffObj.added) {
            //需要展示在当前结果位置的数据
            let dealedContent = ''
            if (diffObj.addContent) {
              dealedContent = diffObj.addContent
            } else {
              //判断下一个项
              if (next && next.removed) {
                //说明两个项之前是对应的关系
               //判断在不同的这行中,具体到字段的不同位置
                let testDiffList = jsDiff.diffWordsWithSpace(
                  replaceContent,
                  nextReplceContent
                )
                let { addContent, removeContent } = this.diffText(testDiffList)
                next.removeContent = removeContent
                dealedContent = addContent
              } else {
               //如果想用空白,对没有内容的地方占位 start
               removedList.push('<span  style="visibility:hidden;">' + replaceContent +'</span>')
               //如果想用空白,对没有内容的地方占位 end
                dealedContent =
                  '<span  style="color:red">' +
                   replaceContent.replace(/\s/gm, '&ensp;')+
                  '</span>'
              }
            }
            addedList.push(dealedContent)
          } else {
            //没有改动的部分
            replaceContent = replaceContent.replace(/\s/gm, '&ensp;')
            addedList.push(
              '<p>' + replaceContent + '</p>'
            )
            removedList.push(
              '<p>' + replaceContent + '</p>'
            )
          }
        })
       let addedHtml = addedList.join('')
       let removedHtml = removedList.join('')
       return {
           addedHtml ,
           removedHtml 
       }
    },
  //对比行内容差异并且拼接结果
    diffText(result) {
      // 当前的数据
      let addList = []
      //历史数据
      let removeList = []
      result.forEach((item) => {
        let value = item.value.replace(/\s/gm, '&ensp;')
        if (item.added) {
          addList.push(
            '<span style="color:red">' + value + '</span>'
          )
        } else if (item.removed) {
          removeList.push(
            '<span  style="color:red">' + value + '</span>'
          )
        } else {
          removeList.push('<span>' + value + '</span>')
          addList.push('<span>' + value + '</span>')
        }
      })
      return {
        addContent: addList.join(''),
        removeContent: removeList.join(''),
      }
    },
    //处理换行和空格
    replaceContent(content) {
      let text = content
      if (content.indexOf('\n') >= 0) {
        //换行替换为<br/>
        // 空格替换为&ensp;
        const reg1 = new RegExp('\n', 'g')
        text = text.replace(reg1, '<br/>')
      }
      return text
    },
三、实现效果

相关文章

网友评论

      本文标题:json对比,并标红差异部分

      本文链接:https://www.haomeiwen.com/subject/cvdgzltx.html