vue2引入monaco-editor,封装以及常见问题踩坑总结
十分重要,首先,要找到跟当前vue版本匹配的monaco-editor版本,我是用的是vue2.x,尝试了最高支持的版本是monaco-editor 0.30.1,同时要实现代码提示需要引入与之匹配的的monaco-editor-webpack-plugin,这里我引入的是 6.0.0,亲测能完美实现代码提示。这几天使用业务中有一个需求是需要做代码在线编辑,因此对比了下首先想到了monaco-ed
这几天使用业务中有一个需求是需要做代码在线编辑,因此对比了下首先想到了monaco-editor,但是实测引入到项目中会遇到一些坑点,因此将引入流程和坑点进行梳理。
踩坑点:
1、monaco-editor版本问题!!十分重要,首先,要找到跟当前vue版本匹配的monaco-editor版本,我是用的是vue2.x,尝试了最高支持的版本是monaco-editor 0.30.1,同时要实现代码提示需要引入与之匹配的的monaco-editor-webpack-plugin,这里我引入的是 6.0.0,亲测能完美实现代码提示。
2、使用 this.$emit('input', this.monacoEditor.getValue()) 来实现双向绑定会导致光标乱跳动,所以最终还是使用this.$emit('change', this.monacoEditor.getValue())进行编辑器内代码内容传递。
引入monaco-editor并封装成通用组件详细步骤:
step1.安装与你vue版本匹配的monaco-editor和与之匹配的monaco-editor-webpack-plugin,这里我先用的是0.30.1+monaco-editor-webpack-plugin 6.0.0。
npm install monaco-editor@0.30.1
npm install monaco-editor-webpack-plugin@6.0.0
step2.创建一个可复用的组件来实现自己想要的编辑器的一些逻辑及配置
<template>
<div ref="main" style="width: 100%; height: 100%"></div>
</template>
<script>
import * as monaco from "monaco-editor";
export default {
name:"CodeEditor",
data() {
return {
monacoEditor: null,
};
},
props:{
language:String,
value:String
},
created() {
},
watch:{
value(newCode) {
this.monacoEditor.setValue(newCode);
}
},
mounted() {
this.$nextTick(()=>{
this.initMonaco();
this.initCustomLanguage();
})
},
methods: {
initMonaco() {
this.monacoEditor = monaco.editor.create(this.$refs.main, {
theme: "vs-dark", // 主题
value: this.value, // 默认显示的值
language: this.language,
folding: true, // 是否折叠
foldingHighlight: true, // 折叠等高线
foldingStrategy: "auto", // 折叠方式
showFoldingControls: "always", // 是否一直显示折叠
disableLayerHinting: true, // 等宽优化
emptySelectionClipboard: false, // 空选择剪切板
selectionClipboard: false, // 选择剪切板
automaticLayout: true, // 自动布局
codeLens: true, // 代码镜头
scrollBeyondLastLine: false, // 滚动完最后一行后再滚动一屏幕
colorDecorators: true, // 颜色装饰器
accessibilitySupport: "on", // 辅助功能支持"auto" | "off" | "on"
lineNumbers: "on", // 行号 取值: "on" | "off" | "relative" | "interval" | function
lineNumbersMinChars: 4, // 行号最小字符 number
enableSplitViewResizing: false,
readOnly: false, //是否只读 取值 true | false
fontSize:18
});
this.monacoEditor.onDidChangeModelContent(() => {
this.$emit('change', this.monacoEditor.getValue());
});
}
},
};
</script>
step3.实现一些自己常用语言的关键词提示功能,目测monaco-editor只有html,css和js的代码提示,所以我这边要想实现golang和python的下来提示就需要把常用关键词给它喂进去,先创建两个存放提示词的js文件。
// go-suggestion.js 用于存放golang的提示词
const goSuggestion=[
"break", "case", "chan", "const", "continue", "default", "defer", "else",
"fallthrough", "for", "func", "go", "goto", "if", "import", "interface",
"map", "package", "range", "return", "select", "struct", "switch", "type",
"var", "append", "cap", "close", "complex", "copy", "delete", "imag", "len",
"make", "new", "panic", "print", "println", "real", "recover","string",
// 常用库关键词
"bufio", "bytes", "context", "crypto", "database", "encoding", "errors",
"flag", "fmt", "io", "log", "math", "net", "os", "path", "reflect", "regexp",
"runtime", "sort", "strconv", "strings", "sync", "syscall", "testing", "text",
"time", "unicode", "unsafe"
];
export default goSuggestion;
// python-suggest.js 用于存放python的一些提示词
const suggestion=[
"False", "None", "True", "and", "as", "assert", "async", "await",
"break", "class", "continue", "def", "del", "elif", "else", "except",
"finally", "for", "from", "global", "if", "import", "in", "is", "lambda",
"nonlocal", "not", "or", "pass", "raise", "return", "try", "while", "with",
"yield", "abs", "all", "any", "ascii", "bin", "bool", "bytearray", "bytes",
"callable", "chr", "classmethod", "compile", "complex", "delattr", "dict",
"dir", "divmod", "enumerate", "eval", "exec", "filter", "float", "format",
"frozenset", "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
"input", "int", "isinstance", "issubclass", "iter", "len", "list", "locals",
"map", "max", "memoryview", "min", "next", "object", "oct", "open", "ord",
"pow", "print", "property", "range", "repr", "reversed", "round", "set",
"setattr", "slice", "sorted", "staticmethod", "str", "sum", "super", "tuple",
"type", "vars", "zip","collections", "datetime", "email", "functools", "http", "json", "logging",
"math", "os", "pathlib", "random", "re", "requests", "socket", "sys", "time",
"unittest", "urllib", "uuid"
]
export default suggestion;
然后在编辑器组件中对齐进行引入并添加提示词
<template>
<div ref="main" style="width: 100%; height: 100%"></div>
</template>
<script>
import * as monaco from "monaco-editor";
// 引入自定义提示词
import pythonSuggestion from "@/components/codeeditor/python-suggestion";
import goSuggestion from "@/components/codeeditor/go-suggestion";
const customLanguage={
"go":goSuggestion,
"python":pythonSuggestion
}
export default {
name:"CodeEditor",
data() {
return {
monacoEditor: null,
};
},
props:{
language:String,
value:String
},
created() {
},
watch:{
value(newCode) {
this.monacoEditor.setValue(newCode);
}
},
mounted() {
this.$nextTick(()=>{
this.initMonaco();
// 自定义提示词
this.initCustomLanguage();
})
},
methods: {
initMonaco() {
this.monacoEditor = monaco.editor.create(this.$refs.main, {
theme: "vs-dark", // 主题
value: this.value, // 默认显示的值
language: this.language,
folding: true, // 是否折叠
foldingHighlight: true, // 折叠等高线
foldingStrategy: "auto", // 折叠方式
showFoldingControls: "always", // 是否一直显示折叠
disableLayerHinting: true, // 等宽优化
emptySelectionClipboard: false, // 空选择剪切板
selectionClipboard: false, // 选择剪切板
automaticLayout: true, // 自动布局
codeLens: true, // 代码镜头
scrollBeyondLastLine: false, // 滚动完最后一行后再滚动一屏幕
colorDecorators: true, // 颜色装饰器
accessibilitySupport: "on", // 辅助功能支持"auto" | "off" | "on"
lineNumbers: "on", // 行号 取值: "on" | "off" | "relative" | "interval" | function
lineNumbersMinChars: 4, // 行号最小字符 number
enableSplitViewResizing: false,
readOnly: false, //是否只读 取值 true | false
fontSize:18
});
this.monacoEditor.onDidChangeModelContent(() => {
this.$emit('change', this.monacoEditor.getValue());
});
},
initCustomLanguage(){
let language=this.language;
if(!(Object.keys(customLanguage)).includes(this.language)){
return
}
monaco.languages.registerCompletionItemProvider(this.language, {
provideCompletionItems: function() {
let keywords = customLanguage[language];
let suggestions = keywords.map(function(keyword) {
return {
label: keyword,
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: keyword
};
});
return { suggestions: suggestions };
}
});
},
},
};
</script>
step5.配置vue.config.js,引入monaco-editor-webpack-plugin插件,只有加载了这个插件才有代码提示和高亮效果。
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
config.plugins.push(new MonacoWebpackPlugin({languages:['go','python','javascript','java','css','html']}));
step6.在其他组件引入并使用封装好的代码编辑器。
<template>
<div style="height: 100%;width: 100%">
<CodeEditor @change="codeChange" v-model="code" language="go"></CodeEditor>
</div>
</template>
<script>
import CodeEditor from "@/components/codeeditor/CodeEditor.vue";
export default {
components: {CodeEditor},
data() {
return {
code:"type user struct"
};
},
created() {
},
mounted() {
},
methods: {
codeChange(e){
console.log(e)
},
},
};
</script>
最终实现的效果:
以上便完成了monaco-editor简单的封装和使用,可根据自己的场景进行修改。
更多推荐
所有评论(0)