介绍
MonacoEditor 是微软出品的一个代码编辑器,像vscode、codesandbox等等都是基于实现的。它能做很多事情,例如:
-
代码高亮
-
格式化
-
定制主题
-
多语言支持
-
代码比对
-
…
Monaco Editor
目标功能
-
点击编辑器外部可以向内部插入指定代码块
-
注册自己的js函数到编辑器
-
在线运行js,打印输出结果
-
捕获执行js产生的错误并提示(未实现)
-
增加自定义的类型声明(未实现)
样式比较简单,有兴趣的可以自己clone代码研究一下
安装monaco-editor
基于Vue2.x的版本集成monaco-editor,因为是基于webpack打包的,所以还需要安装**monaco-editor-webpack-plugin,**这里需要注意版本,两个包版本不对对应会出现很多问题。👇
monaco-editor-webpack-plugin
建议和我版本保持统一:
npm install --save-dev monaco-editor monaco-editor-webpack-plugin
引入
配置webpack插件
这里将它封装到一个组件中,方便复用
<template>
<div id="container"></div>
</template>
<script>
import * as monaco from 'monaco-editor'
export default {
name: "MonacoEditor",
props: {
option: {
type: Object,
default: () => {},
},
value: {
type: String,
default: "",
},
},
data() {
return {
editor: null,
};
},
mounted() {
this.initEditor();
},
methods: {
// 初始化
initEditor() {
this.editor = monaco.editor.create(document.getElementById("container"), {
value: this.value, // 内容
language: "javascript", // 使用的语言
...this.option,
});
// 将编辑器的内容双向绑定到父组件中
this.editor.onDidChangeModelContent((event) => {
this.$emit("input", this.editor.getValue(), event);
});
},
}
};
</script>
接下来我们将它引入到App中使用一下
<template>
<div id="app">
<div class="box">
<div class="code_block">
<h3>代码块(点击插入代码块)</h3>
<div class="list">
<div class="item" v-for="item in codeList" :key="item.id" @click="insertCode(item.id)">
{{ item.id }}
</div>
</div>
</div>
<div class="editor">
<MonacoEditor ref="editor" style="height: 500px" :option="options" v-model="code"></MonacoEditor>
</div>
<div class="debugegr">
<button @click="execute">执行</button>
<textarea class="console" :value="output"></textarea>
</div>
</div>
</div>
</template>
<script>
import MonacoEditor from "./components/MonacoEditor.vue";
export default {
name: "App",
data() {
return {
options: {
theme: "vs-dark", // 主题
},
code: ""
};
},
components: {
MonacoEditor,
},
};
</script>
打开界面就可以看到开头如下的效果
实现功能
插入指定代码块
首先我们再data中加一组数据(这块如果函数较多可写到配置文件中):
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
然后增加一个方法,这里其实就是使用自带的api,不用死记硬背
注册自己的方法到编辑器
这个功能官网有对应的示例,就是调用编辑器的方法monaco.languages.registerCompletionItemProvider, 它接受两个参数,第一个参数是你的语言模型(例如javascript),第二个参数是个对象,具体代码如下
我这边的业务是这样的,存在一个全局对象global ,数据结构是树形,使用的方式就是
global.xxx.xxx 这样,所以当输入 . 时,就会触发方法,根据输入内容动态获取目标层级的方法
每一项的结构必须存在 label、kind、insertText
先更新到这,抽空写完。
总结
其实都是api的调用,有其他需求可留言。