如何在vue3中使用monaco-editor首先安装monaco-editor: 然后在vue3中使用:第一步是初始化
首先安装monaco-editor:
npm install monaco-editor
然后在vue3中使用:第一步是初始化函数
<template>
<div class="monaco" id="monaco" ref="monacoRef"></div>
</template>
<script setup>
import * as monaco from 'monaco-editor'
let editor = null
const init = () => {
editor = monaco.editor.create(monacoRef.value, {
value: props.code,
language: props.language,
theme: 'vs-dark',
automaticLayout: true, // 自动调整大小
lineHeight: 24,
tabSize: 2,
minimap: {
// 关闭小地图
enabled: false,
},
readOnly: true,
domReadOnly: true
})
}
onMounted(() => {
init()
})
</script>
此时你会得到一个黑色的代码编辑器:
注意:这里有个坑,如果你用vue3的ref来接收monaco-editor的示例,那么你后面在调用其内部的方法的时候会卡死,在调用前记得用toRaw; 例如:
const editor = ref(null)
toRaw(editor.vlaue).xxx();
好了,现在实现的过于简陋,在业务上咱们需要封装一下 便于使用。比如
- 增加代码跳转到指定行
- 增加代码行数高亮
- 动态设置语言
第一个跳转到指定行:
const setPosition = () => {
if (!editor) {
return;
}
editor.revealLineInCenter(Number(props.line));
}
第二个,代码行数高亮
const highlightLine = () => {
const lineNumber = Number(props.line);
if (lineNumber === 0) {
decorations = editor.deltaDecorations(decorations, []);
return
}
decorations = editor.deltaDecorations(decorations, [
{
range: new monaco.Range(lineNumber, 1, lineNumber, 1),
options: {
isWholeLine: true,
className: 'highlight-line'
}
}
]);
}
第三个,动态设置语言
const setLanguage = () => {
if (!editor) {
return;
}
const model = editor.getModel()
if (!model) {
return
}
monaco.editor.setModelLanguage(model, props.language)
}
注意:这里有个坑,你不能使用像
editor.setModelLanguage(model, props.language)
会报找不到函数;
最后,再加上属性从外部传入。咱们这个组件算是封装完成了。 具体代码如下:
<template>
<div class="monaco" id="monaco" ref="monacoRef"></div>
</template>
<script setup>
import * as monaco from 'monaco-editor'
import {onMounted, ref, onBeforeUnmount, watch} from 'vue'
const props = defineProps({
code: {
type: String,
required: true
},
language: {
type: String,
default: 'xml'
},
line: {
type: Number,
default: 0
}
})
const monacoRef = ref(null)
let editor = null
let decorations = [] // 存储装饰的ID
const highlightLine = () => {
const lineNumber = Number(props.line);
if (lineNumber === 0) {
decorations = editor.deltaDecorations(decorations, []);
return
}
decorations = editor.deltaDecorations(decorations, [
{
range: new monaco.Range(lineNumber, 1, lineNumber, 1),
options: {
isWholeLine: true,
className: 'highlight-line'
}
}
]);
}
const setLanguage = () => {
if (!editor) {
return;
}
const model = editor.getModel()
if (!model) {
return
}
monaco.editor.setModelLanguage(model, props.language)
}
const setPosition = () => {
if (!editor) {
return;
}
editor.revealLineInCenter(Number(props.line));
}
const init = () => {
editor = monaco.editor.create(monacoRef.value, {
value: props.code,
language: props.language,
theme: 'vs-dark',
automaticLayout: true, // 自动调整大小
lineHeight: 24,
tabSize: 2,
minimap: {
// 关闭小地图
enabled: false,
},
readOnly: true,
domReadOnly: true
})
}
const assignmentCode = () => {
if (!editor) {
return
}
editor.setValue(props.code)
if (props.code) {
setLanguage();
setPosition();
highlightLine();
}
}
watch(() => props.code, assignmentCode, { immediate: true,deep: true });
onMounted(() => {
init()
})
onBeforeUnmount(() => {
if (editor) {
editor.dispose();
editor = null
}
});
</script>
<style scoped lang="scss">
.monaco{
width: 100%;
height: 100%;
}
</style>
<style>
#monaco .highlight-line {
background-color: rgba(140, 143, 255, 0.7) !important; /* 设置高亮背景颜色 */
}
</style>
记录一下,万一帮到人了呢!
转载自:https://juejin.cn/post/7415912404653637672