小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
在项目中遇到一个需求,要求对比两段文本的差异,删除的文字要添加删除线,新增的文字标红。本来想自己实现,奈何架不住工期紧迫,于是就去github上,找到这个 jsdiff 非常强大的文本对比JS库来实现,本文记录了 jsdiff 的使用过程。
安装和引入
执行命令 npm install diff --save
安装。
使用import Diff from 'diff'
引入。
如何使用
通过 Diff 对比后返回的是一个数组,其数组项是个对象,对象有以下几个属性:
- value 文本字段
- added 为
true
时表示该字段是新增的 - removed 为
true
时表示该字段是被删除的 - count 文本字段的长度
const Diff = require('diff');
const a = 'This is a very magical shoe. It costs 15 yuan.'
const b = 'this is a strong and beautiful shoe. It only costs 12 yuan.'
const result = Diff.diffChars(a, b);
console.log(result)
jsdiff中提供了很多对比文本的方法,每个方法对应各种的比较方法,每种方法对比后的结果各不相同,下面一一列出来,可以根据需求选择一个适合的方法。
-
Diff.diffChars(oldStr, newStr[, options])
比较两个文本块,逐个字符进行比较。- options
ignoreCase
:true
忽略大小写差异。默认为false
.
- options
-
Diff.diffWords(oldStr, newStr[, options])
比较两个文本块,逐字比较,忽略空格。- options
ignoreCase
:true
忽略大小写差异。默认为false
.
- options
-
Diff.diffWordsWithSpace(oldStr, newStr[, options])
比较两个文本块,逐字比较,空格也比较。 -
Diff.diffLines(oldStr, newStr[, options])
比较两个文本块,逐行比较。- options
ignoreWhitespace
:true
忽略文本头尾空格。newlineIsToken
:true
将换行符视为单独的标记。
- options
-
Diff.diffTrimmedLines(oldStr, newStr[, options])
比较两个文本块,逐行比较,忽略文本头尾空格。 -
Diff.diffSentences(oldStr, newStr[, options])
比较两个文本块,逐句比较。
展示文本差异
根据产品的需求,删除的文字要添加删除线,新增的文字标红,只要遍历对比后的结果拼成一串 DOM 元素通过appendChild
添加到页面的容器的DOM节点中即可。
采用document.createDocumentFragment()
创建一个DOM虚拟节点,遍历中生成的DOM元素都往这个虚拟节点中添加,遍历完成后在一次性添加到页面的容器的DOM节点中,避免页面一直重绘。
实现代码:
<template>
<div id="display"></div>
</template>
<script>
const Diff = require('diff');
export default {
data() {
return {}
},
mounted() {
const a = 'This is a very magical shoe. It costs 15 yuan.'
const b = 'This is a strong and beautiful shoe. It only costs 12 yuan.'
const result = Diff.diffChars(a, b);
const virtualDOM = document.createDocumentFragment();
result.forEach((part) => {
span = document.createElement('span');
span.style.color = part.added ? 'red' : '#333333';;
if (part.removed) {
span.style['text-decoration'] = 'line-through';
}
span.appendChild(document.createTextNode(part.value));
virtualDOM.appendChild(span);
});
document.getElementById('content').appendChild(virtualDOM);
}
}
</script>
下面来展示一下调用各种Diff方法的效果。
-
diffChars
-
diffWords
- diffWordsWithSpace
- diffTrimmedLines
- diffSentences
根据需求来选择合适的Diff方法。