一、安装引入依赖
安装依赖
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, ' ')+
'</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, ' ')+
'</span>'
}
}
addedList.push(dealedContent)
} else {
//没有改动的部分
replaceContent = replaceContent.replace(/\s/gm, ' ')
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, ' ')
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/>
// 空格替换为 
const reg1 = new RegExp('\n', 'g')
text = text.replace(reg1, '<br/>')
}
return text
},
网友评论