vue下使用Monaco Editor


vue下使用Monaco Editor

1.簡介

​ Monaco Editor是為VS Code提供支持的代碼編輯器。描述代碼編輯器的功能,良好的網頁是在這里。它已獲得MIT許可,並支持Classic Edge,Edge,Chrome,Firefox,Safari和Opera。移動瀏覽器或移動Web框架支持Monaco編輯器(但移動的有的瀏覽器是支持的,起碼我用的幾個都支持)。

2.開始

2.1 安裝環境

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> <!--寬高自行設定 -->
import * as monaco from 'monaco-editor'
export default{
    data(){
        return {
            editor:null,//文本編輯器
        }
    },
    mounted(){
      this.initEditor();  
    },
    methods:{
        initEditor(){
            // 初始化編輯器,確保dom已經渲染
            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

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

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

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

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

至此,最簡單的文檔編輯器已經完成。

3. 進階

3.1 文件改動狀態

export default{
    data(){
        return {
            editor:null,//文本編輯器
            isSave:true,//文件改動狀態,是否保存
            oldValue:'' //保存后的文本
        }
    },
    methods:{
        initEditor(){
            // 初始化編輯器,確保dom已經渲染
            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(() => {
                // 當鍵盤按下,判斷當前編輯器文本與已保存的編輯器文本是否一致
                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已經渲染
            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();//獲取舊的文本
            //創建新模型,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();
            }
            //設置新模型
            this.editor.setModel(newModel);
        }
    }
}

3.3 更改編輯器配置

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

3.4 觸發編輯器事件

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

3.5 獲取選中內容

//獲取編輯器選中的參數,包括起始行等等
var selection = this.editor.getSelection();
//獲取當前選中的文本
var text = currentFn(editor,selection.startLineNumber,selection.startColumn,selection.endLineNumber,selection.endColumn);
function currentFn(monacoEditor, startLineNumber, startColumn, endLineNumber, endColumn) {
    let currentText = '' //選中文字的內容
    let num = 0;//累計回車的數量
    let startIndex = null;//截取編輯器內容的起始下標
    let endIndex = null;//截取編輯器內容的結束下標
    // monacoEditor.getValue().split('')  :  獲取編輯器內容,並拆成數組,並把每一個字符作為數組的每一項
    if (startLineNumber < endLineNumber) {//當起始行<結束行(方向:從上到下,從左到右)
        monacoEditor.getValue().split('').map((item, index) => {
            if (startLineNumber === 1) {//判斷起始行當前行數,為1 則前面沒有回車
            startIndex = startColumn - 1;//獲取起始下標
            if (item === '\n') {
                num += 1;//累計回車數量(針對於結束行)
                if (num === endLineNumber - 1) {//獲取結束行最近的回車的下標+結束行的結束列
                endIndex = index + endColumn
                }
            }
            } else {//判斷起始行當前行數,大於1 則前面有回車
            if (item === '\n') {//累計回車數量
                num += 1
                if (num === startLineNumber - 1) {//獲取起始行最近的回車的下標+起始行的起始列
                startIndex = index + startColumn
                }
                if (num === endLineNumber - 1) {//獲取結束行最近的回車的下標+結束行的結束列
                endIndex = index + endColumn
                }
            }
            }
        })
    } else if (startLineNumber > endLineNumber) {//當起始行>結束行(方向:從下到上,從右到左)
        monacoEditor.getValue().split('').map((item, index) => {
            if (endLineNumber === 1) {//判斷結束行當前行數,為1 則前面沒有回車
            startIndex = endColumn - 1;//獲取起始下標
            if (item === '\n') {
                num += 1;//累計回車數量(針對於起始行)
                if (num === startLineNumber - 1) {//獲取結束下標:起始行最近的回車的下標+起始行的起始列
                endIndex = index + startColumn
                }
            }
            } else {//判斷結束行當前行數,大於1 則前面有回車
            if (item === '\n') {//累計回車數量
                num += 1
                if (num === endLineNumber - 1) {//獲取結束行最近的回車的下標+結束行的結束列
                startIndex = index + endColumn
                }
                if (num === startLineNumber - 1) {//獲取起始行最近的回車的下標+起始行的起始列
                endIndex = index + startColumn
                }
            }
            }
        })
    } else if (startLineNumber === endLineNumber) {//當起始行=結束行(方向:從左到右,從右到左)
        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) {
        // 獲取當前行數
        const line = position.lineNumber;

        // 獲取當前列數
        const column = position.column;
        // 獲取當前輸入行的所有內容
        const content = model.getLineContent(line)
        // 通過下標來獲取當前光標后一個內容,即為剛輸入的內容
        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 == "$"){
            //...
            //攔截到用戶輸入$,開始設置提示內容,同else中代碼一致,自行拓展
        }else{
            //直接提示,以下為sql語句關鍵詞提示
            var sqlStr = ['SELECT','FROM','WHERE','AND','OR','LIMIT','ORDER BY','GROUP BY'];
            for(var i in sqlStr){
                suggestions.push({
                    label: sqlStr[i], // 顯示的提示內容
                    kind: monaco.languages.CompletionItemKind['Function'], // 用來顯示提示內容后的不同的圖標
                    insertText: sqlStr[i], // 選擇后粘貼到編輯器中的文字
                    detail: '', // 提示內容后的說明
                    range:range
                });
            }
        }
        return {
            suggestions: suggestions
        };
    },
    triggerCharacters: ["$",""]
});


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM