Vue3 利用monaco Diff Editor實現(xiàn)代碼compare

前情提要

場景: 產(chǎn)品要求實現(xiàn)兩個json的前后對比的功能麸俘,以提供快速查看修改內(nèi)容穷躁,類似于vscode里面的working tree.

問題: 既然功能類似于vscode,而vscode的底層代碼編輯器就是monaco editor,所以利用微軟出的基于瀏覽器的編輯器monaco來實現(xiàn)需求~

基礎(chǔ)步驟

  1. 安裝monaco editor
npm install monaco-editor -S
  1. 引入并初始化實例

創(chuàng)建一個container

<template>
  <div
    ref="container"
    class="monaco-editor"
    :style="'height: ' + height + 'px'"
  ></div>
</template>

引入monaco 初始化這個container

import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
let originalModel;
let modifiedModel;
let monacoDiffInstance;
const container = ref(null);
function init() {
  // 初始化編輯器實例
  monacoDiffInstance = monaco.editor.createDiffEditor(
    container.value,
    //配置項
    defaultOpts
  );
  originalModel = monaco.editor.createModel(
    oldValue,
    'json'
  );
  modifiedModel = monaco.editor.createModel(
    newvalue,
    'json'
  );
  monacoDiffInstance.setModel({
    original: originalModel,
    modified: modifiedModel,
  });
}

在做編輯器實例的初始化時狞山,定義originalModel modifiedModel monacoDiffInstance變量時码泞,使用ref()reactive()來定義上述響應(yīng)式變量都無法生效吱涉,這里如果有懂的大神可以指教一下..

  1. 設(shè)置配置項
const defaultOpts = reactive({
  value: "",
  theme: "vs", // 編輯器主題:vs, hc-black, or vs-dark逛薇,更多選擇詳見官網(wǎng)https://microsoft.github.io/monaco-editor/docs.html
  roundedSelection: false, // 右側(cè)不顯示編輯器預(yù)覽框
  autoIndent: true, // 自動縮進
  readOnly: true, // 是否只讀
  diffWordWrap:true,
  wordWrap:'on',
  automaticLayout:true,
  scrollBeyondLastLine:false,
  scrollbar:{
    verticalScrollbarSize: 0
  },
});

這里吐槽一下..這個官方文檔實在是太難讀了捺疼,想要通過配置修改一個很簡單的功能要在里面繞半天..給大家推薦一個中文版文檔雖然也不是特別好找但是最起碼先解決了language的問題????https://aydk.site/editor/

封裝組件

以上已經(jīng)實現(xiàn)了最基本的對比編輯器的功能了,接下來封裝就是基礎(chǔ)操作了~


// desc: 基于monaco的diff editor 
// feat:支持Json文件對比
// usage: <diffEditor
//          ref="monacoContainer"
//         :oldValue="oldValue" //舊值
//          :value="value"  //新值
//         :visible="editorVisible"
//          style="width: 100%"
//        ></diffEditor>
<template>
  <div
    ref="container"
    class="monaco-editor"
    :style="'height: ' + height + 'px'"
  ></div>
</template>

<script setup>
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
import {
  defineProps,
  reactive,
  ref,
  defineEmits,
  watch,
nextTick,
onBeforeUnmount,
} from "vue";

const props = defineProps({
  language: {
    type: String,
    default: "json",
  },
  oldValue: String,
  value: String,
  visible: Boolean,
  height: {
    type: Number,
    default: 380,
  },
});

watch(
  () => props.oldValue,
  (newValue) => {
    originalModel = monaco.editor.createModel(newValue, props.language);
    monacoDiffInstance.setModel({
      original: originalModel,
      modified: modifiedModel,
    });
  },
  { deep: true }
);
watch(
  () => props.value,
  (newValue) => {
    modifiedModel = monaco.editor.createModel(newValue, props.language);
    monacoDiffInstance.setModel({
      original: originalModel,
      modified: modifiedModel,
    });
  },
  { deep: true }
);
watch(
  () => props.visible,
  (newValue) => {
    newValue && nextTick(()=>{init()})
  },
  {
    immediate: true,
  }
);
const defaultOpts = reactive({
  value: "",
  theme: "IDLE", // 編輯器主題:vs, hc-black, or vs-dark永罚,更多選擇詳見官網(wǎng)
  roundedSelection: false, // 右側(cè)不顯示編輯器預(yù)覽框
  autoIndent: true, // 自動縮進
  readOnly: true, // 是否只讀
  diffWordWrap:true,
  wordWrap:'on',
  automaticLayout:true,
  scrollBeyondLastLine:false,
  scrollbar:{
    verticalScrollbarSize: 0
  },
});
let originalModel;
let modifiedModel;
let monacoDiffInstance;
const container = ref(null);
function init() {
  monaco.editor.defineTheme('IDLE', Theme);
  monaco.editor.setTheme('IDLE')
  // 初始化編輯器實例
  monacoDiffInstance = monaco.editor.createDiffEditor(
    container.value,
    defaultOpts
  );
  originalModel = monaco.editor.createModel(
    JSON.stringify(JSON.parse(props.oldValue), null, "\t"),
    props.language
  );
  modifiedModel = monaco.editor.createModel(
    JSON.stringify(JSON.parse(props.value), null, "\t"),
    props.language
  );
  monacoDiffInstance.setModel({
    original: originalModel,
    modified: modifiedModel,
  });
}
onBeforeUnmount(()=>{
    monacoDiffInstance.dispose()
})
</script>

<style lang="less">
.the-code-diff-editor-container {
  width: 100%;
  height: 100%;
  overflow: auto;
  .monaco-editor .scroll-decoration {
    box-shadow: none;
  }
}
</style>

OK~~~完結(jié)撒花??...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末啤呼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子呢袱,更是在濱河造成了極大的恐慌官扣,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羞福,死亡現(xiàn)場離奇詭異惕蹄,居然都是意外死亡,警方通過查閱死者的電腦和手機治专,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門卖陵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人张峰,你說我怎么就攤上這事泪蔫。” “怎么了挟炬?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵鸥滨,是天一觀的道長嗦哆。 經(jīng)常有香客問我,道長婿滓,這世上最難降的妖魔是什么老速? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮凸主,結(jié)果婚禮上橘券,老公的妹妹穿的比我還像新娘。我一直安慰自己卿吐,他們只是感情好旁舰,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗡官,像睡著了一般箭窜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衍腥,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天磺樱,我揣著相機與錄音,去河邊找鬼婆咸。 笑死竹捉,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的尚骄。 我是一名探鬼主播块差,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼倔丈!你這毒婦竟也來了憨闰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤乃沙,失蹤者是張志新(化名)和其女友劉穎起趾,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體警儒,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年眶根,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜀铲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡属百,死狀恐怖记劝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情族扰,我是刑警寧澤厌丑,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布定欧,位于F島的核電站,受9級特大地震影響怒竿,放射性物質(zhì)發(fā)生泄漏砍鸠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一耕驰、第九天 我趴在偏房一處隱蔽的房頂上張望爷辱。 院中可真熱鬧,春花似錦朦肘、人聲如沸饭弓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弟断。三九已至,卻和暖如春趴生,著一層夾襖步出監(jiān)牢的瞬間夫嗓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工冲秽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舍咖,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓锉桑,卻偏偏與公主長得像排霉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子民轴,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容