vue3-element-admin集成monaco-editor
安装依赖
执行命令:
pnpm install monaco-editor
配置 vite.config.ts
在 optimizeDeps 中新增monaco所需组件
// 预加载项目必需的组件
optimizeDeps: {
include: [
"monaco-editor/esm/vs/language/json/json.worker",
"monaco-editor/esm/vs/language/css/css.worker",
"monaco-editor/esm/vs/language/html/html.worker",
"monaco-editor/esm/vs/language/typescript/ts.worker",
"monaco-editor/esm/vs/editor/editor.worker",
],
},
自定义组件
在src/components下新增目录 MonacoEditor,在该目录下新建 index.vue , 内容如下:
<template>
<div class="editor" ref="dom"></div>
</template>
<script lang="ts">
import { onMounted, ref, defineComponent, watch, onUnmounted, shallowRef } from "vue";
import * as monaco from "monaco-editor";
import EditorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
//https://github.com/vitejs/vite/discussions/1791
export default defineComponent({
name: "vsCode",
props: {
modelValue: {
type: String,
default: ""
},
theme: {
type: String,
default: "vs"
},
language: { type: String, default: "json" },
options: Object
},
emits: ["change", "update:modelValue"],
setup(props, { emit }) {
const dom = ref();
const vs = shallowRef();
const self: any = window;
self.MonacoEnvironment = {
getWorker() {
return new EditorWorker();
}
};
onMounted(() => {
const editor = monaco.editor.create(dom.value, {
model: monaco.editor.createModel(props.modelValue, props.language),
tabSize: 2,
automaticLayout: true,
scrollBeyondLastLine: false,
theme: props.theme,
...props.options
});
vs.value = editor;
editor.onDidChangeModelContent(() => {
const value = editor.getValue();
emit("update:modelValue", value);
emit("change", value);
});
watch(
() => props.modelValue,
(vl) => {
if (vl !== editor.getValue()) {
editor.setValue(vl);
}
}
);
watch(
() => props.theme,
(vl) => {
monaco.editor.setTheme(vl);
}
);
watch(
() => props.language,
(vl) => {
monaco.editor.setModelLanguage(editor.getModel() as monaco.editor.ITextModel, vl);
}
);
watch(
() => props.options,
(vl) => {
editor.updateOptions(vl as monaco.editor.IEditorOptions);
}
);
});
onUnmounted(() => {
vs.value && vs.value.dispose();
});
return { dom };
}
});
</script>
<style scoped>
.editor {
height: 100%;
}
</style>
全局注册组件
在 components.d.ts 增加如下代码:
declare module "vue" {
export interface GlobalComponents {
MonacoEditor: (typeof import("../components/MonacoEditor/index.vue"))["default"];
}
}
使用组件
<template>
<MonacoEditor class="editor" v-model="formData.content" theme="vs" language="java"
style="width:100%; height: 420px; border: 1px solid #ccc" />
</template>
<script setup lang="ts">
/**
* 引入 MonacoEditor 组件
* */
import MonacoEditor from "@/components/MonacoEditor/index.vue";
const formData = reactive({
content: "", // 存储编辑器内容
});
</script>