likes
comments
collection
share

如何在vue3中使用monaco-editor首先安装monaco-editor: 然后在vue3中使用:第一步是初始化

作者站长头像
站长
· 阅读数 22

首先安装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中使用monaco-editor首先安装monaco-editor: 然后在vue3中使用:第一步是初始化

注意:这里有个坑,如果你用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
评论
请登录