需要安装 deep-diff diff
npm install deep-diff
npm install diff
新建 js 脚本文本,内容如下
let observableDiff = require('deep-diff/dist/deep-diff.min').observableDiff;
let Diff = require('diff/dist/diff.min');
/**
* 深度比较两个对象是否相同
* @param {Object} oldData
* @param {Object} newData
*/
function deepCompare(oldData, newData) {
// 类型为基本类型时,如果相同,则返回true
if (oldData === newData) return true;
if (isObject(oldData) && isObject(newData) && Object.keys(oldData).length === Object.keys(newData).length) {
// 类型为对象并且元素个数相同
// 遍历所有对象中所有属性,判断元素是否相同
for (const key in oldData) {
if (oldData.hasOwnProperty(key)) {
if (!deepCompare(oldData[key], newData[key]))
// 对象中具有不相同属性 返回false
return false;
}
}
} else if (isArray(oldData) && isArray(oldData) && oldData.length === newData.length) {
// 类型为数组并且数组长度相同
for (let i = 0, length = oldData.length; i < length; i++) {
if (!deepCompare(oldData[i], newData[i]))
// 如果数组元素中具有不相同元素,返回false
return false;
}
} else {
// 其它类型,均返回false
return false;
}
// 走到这里,说明数组或者对象中所有元素都相同,返回true
return true;
}
function judgeType(change) {
if (arguments.length == 0) {
return ''; //无参数传入
}
if (change === null) {
return 'null'
}
if (change === undefined && arguments.length > 0) {
return 'undefined'
}
if (change instanceof Function) {
return 'function'
}
if (Object.prototype.toString.call(change) == "[object Object]") {
return 'object'
}
if (change instanceof Array) {
return 'arry'
}
if (change instanceof Number || typeof change == 'number') {
return 'number'
}
if (change instanceof String || typeof change == 'string') {
return 'string'
}
if (change instanceof Boolean || typeof change == 'boolean') {
return 'boolean'
}
}
/***
* isSamePath 比较是否有删除项
* */
function isSamePath(diff, path) {
let D = diff['D'] || [];
let tmp = null;
for (let i = 0; i < D.length; i++) {
tmp = D[i].path; //
if (deepCompare(tmp, path)) {
return true
}
}
return false;
}
function turnArrToTable(arr) {
let thead = null;
let tr = arr.map(item => {
// console.log(item);
let td = [];
let th = [];
for (let k in item) {
if (!thead) {
th.push(`<th>${k}</th>`)
}
td.push(`<td>${item[k]}</td>`)
}
if (!thead) {
thead = `<tr>${th.join('')}</tr>`;
}
return `<tr>${td.join('')}</tr>`
});
let table = `<table><thead>${thead}</thead><tbody>${tr.join('')}</tbody></table>`;
return table;
}
function getCompareValue(tree, path) {
let res = tree;
for (let val of path) {
res = res ? res[val] : '';
}
return res;
}
export function toForm(obj, compare) {
let diff = null;
if (compare) {
diff = delRow(obj, compare);
}
function getRichText(obj, path = [], tree = 1) {
let str = '';
if (judgeType(obj) == 'object') {
console.log(obj,'22222')
for (let k in obj) {
let nextPath = [...path, k];
if (judgeType(obj[k]) == 'object' || (judgeType(obj[k]) == 'arry' && judgeType(obj[k][0])=='object')) { //
str += `<div class='form-${tree} ${isSamePath(diff, nextPath) ? "delRow" : ""}'>
<p class='form-title form-title-${tree}'>${k}</p>
<div class='form-body form-body-${tree}'>${getRichText(obj[k], nextPath, tree + 1)}</div>
</div>`
} else {
str += `<div class='form-${tree} ${isSamePath(diff, nextPath) ? "delRow flex" : "flex"}'>
<p class=' form-label form-label-${tree}'>${k}:</p>
<div class='form-value form-value-${tree}'>${getRichText(obj[k], nextPath, tree + 1)}</div>
</div>`
}
}
} else if (judgeType(obj) == 'arry') {
// for (let i = 0; i < obj.length; i++) {
// toForm(obj[i])
// }
if(judgeType(obj[0]) !== 'object') {
return getRichText(obj.join('、'))
} else {
return turnArrToTable(obj)
}
} else {
let tmp = getCompareValue(compare, path);
return editStr(obj, tmp)
}
return str
}
return getRichText(obj)
}
export function delRow(obj1, obj2) {
let diff = {};
observableDiff(obj1, obj2, function (d) {
diff[d.kind] = diff[d.kind] || [];
diff[d.kind].push(d)
});
return diff;
}
export function editStr(str1, str2) {
if (str1 && str2) {
let str = '';
const diff = Diff.diffChars(str1 + '', str2 + '');
diff.forEach((part) => {
switch (part.added ? 'add' : part.removed ? 'del' : 'same') {
case 'del':
str += `<span class='del'>${part.value}</span>`
break;
case 'same':
str += `<span class='same'>${part.value}</span>`
break;
}
});
return str
}
return str1
}
使用
引入上方定义的脚本文件
import {toForm} from '脚本文件路径'
定义方法
change(before, after) {
this.form1 = toForm(before, after);
this.form2 = toForm(after, before);
}
使用方法
this.change("需要比对的内容11111", "需要比对的内容222");
文本显示内容
<div class='before' v-html='form1'>
</div>
<div class='after' v-html='form2'>
</div>
css设置
.before .del{
color:red;
}
.after .del{
color:blue;
}