vue下使用Monaco Editor

vue下使用Monaco Editor

1.簡介

? Monaco Editor是為VS Code提供支持的代碼編輯器。描述代碼編輯器的功能,良好的網(wǎng)頁是在這里萨醒。它已獲得MIT許可并鸵,并支持Classic Edge,Edge捌蚊,Chrome集畅,F(xiàn)irefox,Safari和Opera缅糟。移動瀏覽器或移動Web框架支持Monaco編輯器(但移動的有的瀏覽器是支持的挺智,起碼我用的幾個都支持)。

2.開始

2.1 安裝環(huán)境

npm install monaco-editor@0.21.2 --save
npm install monaco-editor-webpack-plugin --save //這個必須安裝窗宦,不然起不來

2.2 配置文件

修改webpack.base.conf.js配置文件赦颇。(前幾步借鑒時間脫臼大神博客,步驟大同小異)

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
  ...
  plugins: [
    ...
    new MonacoWebpackPlugin()
  ]
};

2.3 開始使用

新建vue文件赴涵,添加如下代碼即可使用

<div id="container"></div> <!--寬高自行設(shè)定 -->
import * as monaco from 'monaco-editor'
export default{
    data(){
        return {
            editor:null,//文本編輯器
        }
    },
    mounted(){
      this.initEditor();  
    },
    methods:{
        initEditor(){
            // 初始化編輯器媒怯,確保dom已經(jīng)渲染
            this.editor = monaco.editor.create(document.getElementById('container'), {
                value:'',//編輯器初始顯示文字
                language:'sql',//語言支持自行查閱demo
                automaticLayout: true,//自動布局
                theme:'vs-dark' //官方自帶三種主題vs, hc-black, or vs-dark
            });
        },
        getValue(){
            this.editor.getValue(); //獲取編輯器中的文本
        }
    }
}

附:Monaco Editor demo

image-20201012143856748.png

附:語言支持(當(dāng)然支持自定義語言)

//modesIds即為支持語言
var modesIds = monaco.languages.getLanguages().map(function(lang) { return lang.id; });

附:配置項(根據(jù)自身需要在初始化編輯器是配置) 配置項鏈接

selectOnLineNumbers: true,//顯示行號
roundedSelection: false,
readOnly: false,        // 只讀
cursorStyle: 'line',        //光標(biāo)樣式
automaticLayout: false, //自動布局
glyphMargin: true,  //字形邊緣
useTabStops: false,
fontSize: 28,       //字體大小
autoIndent:true,//自動布局
quickSuggestionsDelay: 500,   //代碼提示延時

至此,最簡單的文檔編輯器已經(jīng)完成髓窜。

3. 進(jìn)階

3.1 文件改動狀態(tài)

export default{
    data(){
        return {
            editor:null,//文本編輯器
            isSave:true,//文件改動狀態(tài)扇苞,是否保存
            oldValue:'' //保存后的文本
        }
    },
    methods:{
        initEditor(){
            // 初始化編輯器,確保dom已經(jīng)渲染
            this.editor = monaco.editor.create(document.getElementById('container'), {
                value:'',//編輯器初始顯示文字
                language:'sql',//語言支持自行查閱demo
                automaticLayout: true,//自動布局
                theme:'vs-dark' //官方自帶三種主題vs, hc-black, or vs-dark
            });
            this.editor.onKeyUp(() => {
                // 當(dāng)鍵盤按下,判斷當(dāng)前編輯器文本與已保存的編輯器文本是否一致
                if(this.editor.getValue() != this.oldValue){
                    this.isSave = false;
                }
            });
        },
        //保存編輯器方法
        saveEditor(){
            this.oldValue = this.editor.getValue();
            ...保存邏輯
        }
    }
}

3.2 更改編輯器語言

export default{
    data(){
        return {
            editor:null,//文本編輯器
        }
    },
    methods:{
        initEditor(){
            // 初始化編輯器杨拐,確保dom已經(jīng)渲染
            this.editor = monaco.editor.create(document.getElementById('container'), {
                value:'',//編輯器初始顯示文字
                language:'sql',//語言支持自行查閱demo
                automaticLayout: true,//自動布局
                theme:'vs-dark' //官方自帶三種主題vs, hc-black, or vs-dark
            });
        },
        changeModel(){
            var oldModel = this.editor.getModel();//獲取舊模型
            var value = this.editor.getValue();//獲取舊的文本
            //創(chuàng)建新模型祈餐,value為舊文本,id為modeId哄陶,即語言(language.id)
            //modesIds即為支持語言
            //var modesIds = monaco.languages.getLanguages().map(function(lang) { return lang.id; });
            var newModel = monaco.editor.createModel(value,id);
            //將舊模型銷毀
            if(oldModel){
                oldModel.dispose();
            }
            //設(shè)置新模型
            this.editor.setModel(newModel);
        }
    }
}

3.3 更改編輯器配置

//此例為更改編輯器為只讀模式,其余以此類推
this.editor.updateOptions({readOnly:true})

3.4 觸發(fā)編輯器事件

//此為格式化代碼,anything無用帆阳,后一個參數(shù)為action事件,自行查找屋吨,我也就找到這么一個
this.editor.trigger('anything','editor.action.formatDocument');

3.5 獲取選中內(nèi)容

//獲取編輯器選中的參數(shù)蜒谤,包括起始行等等
var selection = this.editor.getSelection();
//獲取當(dāng)前選中的文本
var text = currentFn(editor,selection.startLineNumber,selection.startColumn,selection.endLineNumber,selection.endColumn);
function currentFn(monacoEditor, startLineNumber, startColumn, endLineNumber, endColumn) {
    let currentText = '' //選中文字的內(nèi)容
    let num = 0;//累計回車的數(shù)量
    let startIndex = null;//截取編輯器內(nèi)容的起始下標(biāo)
    let endIndex = null;//截取編輯器內(nèi)容的結(jié)束下標(biāo)
    // monacoEditor.getValue().split('')  :  獲取編輯器內(nèi)容,并拆成數(shù)組至扰,并把每一個字符作為數(shù)組的每一項
    if (startLineNumber < endLineNumber) {//當(dāng)起始行<結(jié)束行(方向:從上到下鳍徽,從左到右)
        monacoEditor.getValue().split('').map((item, index) => {
            if (startLineNumber === 1) {//判斷起始行當(dāng)前行數(shù),為1 則前面沒有回車
            startIndex = startColumn - 1;//獲取起始下標(biāo)
            if (item === '\n') {
                num += 1;//累計回車數(shù)量(針對于結(jié)束行)
                if (num === endLineNumber - 1) {//獲取結(jié)束行最近的回車的下標(biāo)+結(jié)束行的結(jié)束列
                endIndex = index + endColumn
                }
            }
            } else {//判斷起始行當(dāng)前行數(shù)敢课,大于1 則前面有回車
            if (item === '\n') {//累計回車數(shù)量
                num += 1
                if (num === startLineNumber - 1) {//獲取起始行最近的回車的下標(biāo)+起始行的起始列
                startIndex = index + startColumn
                }
                if (num === endLineNumber - 1) {//獲取結(jié)束行最近的回車的下標(biāo)+結(jié)束行的結(jié)束列
                endIndex = index + endColumn
                }
            }
            }
        })
    } else if (startLineNumber > endLineNumber) {//當(dāng)起始行>結(jié)束行(方向:從下到上阶祭,從右到左)
        monacoEditor.getValue().split('').map((item, index) => {
            if (endLineNumber === 1) {//判斷結(jié)束行當(dāng)前行數(shù),為1 則前面沒有回車
            startIndex = endColumn - 1;//獲取起始下標(biāo)
            if (item === '\n') {
                num += 1;//累計回車數(shù)量(針對于起始行)
                if (num === startLineNumber - 1) {//獲取結(jié)束下標(biāo):起始行最近的回車的下標(biāo)+起始行的起始列
                endIndex = index + startColumn
                }
            }
            } else {//判斷結(jié)束行當(dāng)前行數(shù)直秆,大于1 則前面有回車
            if (item === '\n') {//累計回車數(shù)量
                num += 1
                if (num === endLineNumber - 1) {//獲取結(jié)束行最近的回車的下標(biāo)+結(jié)束行的結(jié)束列
                startIndex = index + endColumn
                }
                if (num === startLineNumber - 1) {//獲取起始行最近的回車的下標(biāo)+起始行的起始列
                endIndex = index + startColumn
                }
            }
            }
        })
    } else if (startLineNumber === endLineNumber) {//當(dāng)起始行=結(jié)束行(方向:從左到右濒募,從右到左)
        monacoEditor.getValue().split('').map((item, index) => {
            if (endLineNumber === 1) {
            startIndex = startColumn < endColumn ? startColumn - 1 : endColumn - 1
            endIndex = startColumn > endColumn ? startColumn - 1 : endColumn - 1
            } else {
            if (item === '\n') {
                num += 1
                if (num === endLineNumber - 1) {
                startIndex = startColumn < endColumn ? startColumn + index : endColumn + index
                endIndex = startColumn > endColumn ? startColumn + index : endColumn + index
                }
            }
            }
        })
    }
    currentText = monacoEditor.getValue().slice(startIndex, endIndex)
    return currentText
}

3.6 代碼提示

monaco.languages.registerCompletionItemProvider('sql', {
    provideCompletionItems: function(model, position) {
        // 獲取當(dāng)前行數(shù)
        const line = position.lineNumber;

        // 獲取當(dāng)前列數(shù)
        const column = position.column;
        // 獲取當(dāng)前輸入行的所有內(nèi)容
        const content = model.getLineContent(line)
        // 通過下標(biāo)來獲取當(dāng)前光標(biāo)后一個內(nèi)容,即為剛輸入的內(nèi)容
        const sym = content[column - 2];
        var textUntilPosition = model.getValueInRange({startLineNumber: 1, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column});
        var word = model.getWordUntilPosition(position);
        var range = {
            startLineNumber: position.lineNumber,
            endLineNumber: position.lineNumber,
            startColumn: word.startColumn,
            endColumn: word.endColumn
        };
        //---------------------------------------------------
        //上面的代碼僅僅是為了獲取sym圾结,即提示符
        //---------------------------------------------------
        var suggestions = [];
        if(sym == "$"){
            //...
            //攔截到用戶輸入$瑰剃,開始設(shè)置提示內(nèi)容,同else中代碼一致筝野,自行拓展
        }else{
            //直接提示晌姚,以下為sql語句關(guān)鍵詞提示
            var sqlStr = ['SELECT','FROM','WHERE','AND','OR','LIMIT','ORDER BY','GROUP BY'];
            for(var i in sqlStr){
                suggestions.push({
                    label: sqlStr[i], // 顯示的提示內(nèi)容
                    kind: monaco.languages.CompletionItemKind['Function'], // 用來顯示提示內(nèi)容后的不同的圖標(biāo)
                    insertText: sqlStr[i], // 選擇后粘貼到編輯器中的文字
                    detail: '', // 提示內(nèi)容后的說明
                    range:range
                });
            }
        }
        return {
            suggestions: suggestions
        };
    },
    triggerCharacters: ["$",""]
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市歇竟,隨后出現(xiàn)的幾起案子挥唠,更是在濱河造成了極大的恐慌,老刑警劉巖焕议,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宝磨,死亡現(xiàn)場離奇詭異,居然都是意外死亡号坡,警方通過查閱死者的電腦和手機懊烤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宽堆,“玉大人腌紧,你說我怎么就攤上這事⌒罅ィ” “怎么了壁肋?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵号胚,是天一觀的道長。 經(jīng)常有香客問我浸遗,道長猫胁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任跛锌,我火速辦了婚禮弃秆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘髓帽。我一直安慰自己菠赚,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布郑藏。 她就那樣靜靜地躺著衡查,像睡著了一般。 火紅的嫁衣襯著肌膚如雪必盖。 梳的紋絲不亂的頭發(fā)上拌牲,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音歌粥,去河邊找鬼塌忽。 笑死,一個胖子當(dāng)著我的面吹牛阁吝,可吹牛的內(nèi)容都是我干的砚婆。 我是一名探鬼主播械拍,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼突勇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了坷虑?” 一聲冷哼從身側(cè)響起甲馋,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎迄损,沒想到半個月后定躏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡芹敌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年痊远,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氏捞。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡碧聪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出液茎,到底是詐尸還是另有隱情逞姿,我是刑警寧澤辞嗡,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站滞造,受9級特大地震影響续室,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谒养,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一挺狰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧买窟,春花似錦她渴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疆虚,卻和暖如春苛败,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背径簿。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工罢屈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人篇亭。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓缠捌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親译蒂。 傳聞我的和親對象是個殘疾皇子曼月,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348