如何在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




