Skip to content

stefanieliang/vue-diff-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vue-diff-demo

Project setup

npm install 

Compiles and hot-reloads for development

npm run serve 

Compiles and minifies for production

npm run build 

Lints and fixes files

npm run lint 

0.需求场景

​ 基于web浏览器,实现一个html/代码/文章等两个版本间的对比工具。

1.基础js库

安装
npm install diff --save 
使用
  • Basic example in Node
require('colors'); const Diff = require('diff'); const one = 'beep boop'; const other = 'beep boob blah'; const diff = Diff.diffChars(one, other); diff.forEach((part) => { // green for additions, red for deletions // grey for common parts const color = part.added ? 'green' : part.removed ? 'red' : 'grey'; process.stderr.write(part.value[color]); }); console.log();
  • Basic example in a web page
<pre id="display"></pre> <script src="diff.js"></script> <script> const one = 'beep boop', other = 'beep boob blah', color = '', span = null; const diff = Diff.diffChars(one, other), display = document.getElementById('display'), fragment = document.createDocumentFragment(); diff.forEach((part) => { // green for additions, red for deletions // grey for common parts const color = part.added ? 'green' : part.removed ? 'red' : 'grey'; span = document.createElement('span'); span.style.color = color; span.appendChild(document.createTextNode(part.value)); fragment.appendChild(span); }); display.appendChild(fragment); </script>

2.基于vue封装一个组件

组件CodeDiffChunk
<template> <div class="diff-chunk"> <div v-if="chunk.collapse" class="collapse-tip" @click.once="$emit('expand', chunk.leftIndex, chunk.rightIndex)"> ... 隐藏 {{chunk.lineCount}} 行,点击展开 ... </div> <div v-else class="line" v-for="(line, index) in chunk.lines" :key="index"> <span v-if="chunk.type !== 'blank'" :class="chunk.type">{{chunk.startLineNumber + index}}</span> <span v-else></span> <pre :class="chunk.type">{{line}}</pre> </div> </div> </template> <script> export default { name: 'code-diff-chunk', props: { chunk: { type: Object, default: () => {} } } }; </script>
组件CodeDiffViewer
<template> <div class="diff-viewer"> <h3>{{title}}</h3> <div class="container" v-if="newContent && oldContent"> <div class="left"> <code-chunk v-for="(chunk, index) in splitedLeft" :key="index" :chunk="chunk" @expand="expandChunk" /> </div> <div class="right"> <code-chunk v-for="(chunk, index) in splitedRight" :key="index" :chunk="chunk" @expand="expandChunk" /> </div> </div> <div v-else v-for="(chunk, index) in unifiedResult" :key="index"> <code-chunk :chunk="chunk" :index="index" /> </div> </div> </template>
使用
<template> <div> <h2>diff2</h2> <code-diff-viewer :new-content="newStr" :old-content="oldStr" title="修改" /> </div> </template> <script> import CodeDiffViewer from "./components/CodeDiffViewer"; import { a, b } from "./data"; export default { components: { CodeDiffViewer }, data() { return { oldStr: a, newStr: b }; } }; </script>

3.基于vue实现一个Diff库

安装
yarn add vue-code-diff 
使用
<template> <div> <code-diff :old-string="oldStr" :new-string="newStr" :context="10" /> </div> </template> import CodeDiff from 'vue-code-diff' export default { components: {CodeDiff}, data(){ return { oldStr: 'old code', newStr: 'new code' } } }
参数说明
参数 说明 类型 可选值 默认值
old-string 陈旧的字符串 string
new-string 新的字符串 string
context 不同地方上下间隔多少行不隐藏 number
outputFormat 展示的方式 string line-by-line,side-by-side line-by-line
源码实现

https://github.com/ddchef/vue-code-diff

4.项目地址

https://github.com/stefanieliang/vue-diff-demo

一、diff简介

diff是Unix系统的一个很重要的工具程序。

它用来比较两个文本文件的差异,是代码版本管理的基石之一。你在命令行下,输入:

$ diff <变动前的文件> <变动后的文件>

diff就会告诉你,这两个文件有何差异。它的显示结果不太好懂,下面我就来说明,如何读懂diff。

img

1. diff的三种格式

由于历史原因,diff有三种格式:

  • 正常格式(normal diff)

  • 上下文格式(context diff)

  • 合并格式(unified diff)

2. 示例文件

为了便于讲解,先新建两个示例文件。

第一个文件叫做f1,内容是每行一个a,一共7行。

  a   a   a   a   a   a   a 

第二个文件叫做f2,修改f1而成,第4行变成b,其他不变。

  a   a   a   b   a   a   a 

3. 正常格式的diff

现在对f1和f2进行比较:

$ diff f1 f2

这时,diff就会显示正常格式的结果:

 	4c4 < a --- > b 

4. 上下文格式的diff

上个世纪80年代初,加州大学伯克利分校推出BSD版本的Unix时,觉得diff的显示结果太简单,最好加入上下文,便于了解发生的变动。因此,推出了上下文格式的diff。

它的使用方法是加入c参数(代表context)。

$ diff -c f1 f2

显示结果如下:

  *** f1 2012-08-29 16:45:41.000000000 +0800   --- f2 2012-08-29 16:45:51.000000000 +0800   ***************   *** 1,7 ****    a    a    a   !a    a    a    a   --- 1,7 ----    a    a    a   !b    a    a    a 

这个结果分成四个部分。

5. 合并格式的diff

如果两个文件相似度很高,那么上下文格式的diff,将显示大量重复的内容,很浪费空间。1990年,GNU diff率先推出了"合并格式"的diff,将f1和f2的上下文合并在一起显示。

它的使用方法是加入u参数(代表unified)。

$ diff -u f1 f2

显示结果如下:

  --- f1 2012-08-29 16:45:41.000000000 +0800   +++ f2 2012-08-29 16:45:51.000000000 +0800   @@ -1,7 +1,7 @@    a    a    a   -a   +b    a    a    a 

6. git格式的diff

版本管理系统git,使用的是合并格式diff的变体。

$ git diff

显示结果如下:

  diff --git a/f1 b/f1   index 6f8a38c..449b072 100644   --- a/f1   +++ b/f1   @@ -1,7 +1,7 @@    a    a    a   -a   +b    a    a    a 

参考:读懂diff

二、一个很牛的库

安装
npm install --save diff2html 
Diff2Html Browser Example

Import the stylesheet and the library code

<!-- CSS --> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" /> <!-- Javascripts --> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html.min.js"></script>

It will now be available as a global variable named Diff2Html.

document.addEventListener('DOMContentLoaded', () => { var diffHtml = global.Diff2Html.html('<Unified Diff String>', { drawFileList: true, matching: 'lines', outputFormat: 'side-by-side', }); document.getElementById('destination-elem-id').innerHTML = diffHtml; });
Diff2Html Vue.js Example
<template> <div v-html="prettyHtml" /> </template> <script> import * as Diff2Html from 'diff2html'; import 'diff2html/bundles/css/diff2html.min.css';  export default {  data() {  return {  diffs:  '--- a/server/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go\n+++ b/server/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go\n@@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (\n \n // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n \n+func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {\n+\tr0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))\n+\tn = int(r0)\n+\tif e1 != 0 {\n+\t\terr = errnoErr(e1)\n+\t}\n+\treturn\n+}\n+\n+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n+\n func read(fd int, p []byte) (n int, err error) {\n \tvar _p0 unsafe.Pointer\n \tif len(p) > 0 {\n',  };  },  computed: {  prettyHtml() {  return Diff2Html.html(this.diffs, {  drawFileList: true,  matching: 'lines',  outputFormat: 'side-by-side',  });  },  }, }; </script>
Diff2HtmlUI Browser

Mandatory HTML resource imports

<!-- CSS --> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" /> <!-- Javascripts --> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>

Init

const targetElement = document.getElementById('destination-elem-id'); const configuration = { drawFileList: true, matching: 'lines' }; const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration); // or const diff2htmlUi = new Diff2HtmlUI(targetElement, diffJson, configuration);

Draw

diff2htmlUi.draw();

Syntax Highlight

<!-- Stylesheet --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/github.min.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" /> <!-- Javascripts --> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>

Pass the option highlight with value true or invoke diff2htmlUi.highlightCode() after diff2htmlUi.draw().

document.addEventListener('DOMContentLoaded', () => { const diffString = `diff --git a/sample.js b/sample.js index 0000001..0ddf2ba --- a/sample.js +++ b/sample.js @@ -1 +1 @@ -console.log("Hello World!") +console.log("Hello from Diff2Html!")`; const targetElement = document.getElementById('myDiffElement'); const configuration = { inputFormat: 'json', drawFileList: true, matching: 'lines', highlight: true }; const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration); diff2htmlUi.draw(); diff2htmlUi.highlightCode(); });

三、其他

强大的在线对比工具,可对比的格式有:Text,Images,Pdf,Folders等。

About

基于vue实现一个在线对比diff工具。

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published