Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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
Morty Proxy This is a proxified and sanitized view of the page, visit original site.