SoFunction
Updated on 2025-04-04

Detailed explanation of the tutorial on using Monaco-editor in Vue3

Monaco-editor, a vs code editor, needs to be inherited to the project. Don't talk anymore, just upload the code.

npm address:/package/monaco-editor

Chinese Documentation:/editor/

Install

pnpm add monaco-editor -S
pnpm add vite-plugin-monaco-editor -D

Configuration

import { defineConfig} from 'vite'
 
// vs code editor configurationimport monacoEditorPlugin from 'vite-plugin-monaco-editor'
 
// /config/
export default ({ mode }) => {
  return defineConfig({
    plugins: [
      monacoEditorPlugin({
        languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html']
      })
    ]
  })
}

Package

First, encapsulate a hook as follows:

@/hooks/ 

import * as monaco from 'monaco-editor'
import useCommonStore from '@/store/common'
import { ref, nextTick, onBeforeUnmount } from 'vue'
 
export function useMonacoEditor(language: string = 'javascript') {
  // Editor example  let monacoEditor:  | null = null
  // Target element  const monacoEditorRef = ref<HTMLElement | null>(null)
 
  // Create an instance  function createEditor(editorOption:  = {}) {
    if(!) return
    monacoEditor = (, {
      // Initial model      model: ('', language),
      // Whether to enable preview images      minimap: { enabled: true },
      // Round corners      roundedSelection: true,
      // theme      theme: useCommonStore().mode == 'dark' ? 'vs-dark' : 'vs',
      // Primary key      multiCursorModifier: 'ctrlCmd',
      // Scrollbar      scrollbar: {
        verticalScrollbarSize: 8,
        horizontalScrollbarSize: 8
      },
      // Line number      lineNumbers: 'on',
      // Tab size      tabSize: 2,
      //Font size      fontSize: 16,
      // Control whether the editor should automatically adjust the indentation when the user typed, pasted, moved or minified      autoIndent: 'advanced',
      // Automatic layout      automaticLayout: true,
      ...editorOption
    })
    return monacoEditor
  }
 
  // Format  async function formatDoc() {
    await monacoEditor?.getAction('')?.run()
  }
 
  // Data update  function updateVal(val: string) {
    nextTick(() => {
      if(getOption()) {
        updateOptions({ readOnly: false })
      }
      monacoEditor?.setValue(val)
      setTimeout(async () => {
        await formatDoc()
      }, 10)
    })
  }
 
  //Configuration update  function updateOptions(opt: ) {
    monacoEditor?.updateOptions(opt)
  }
 
  // Get configuration  function getOption(name: ) {
    return monacoEditor?.getOption(name)
  }
 
  // Get an instance  function getEditor() {
    return monacoEditor
  }
 
  // Page leaves Destroy  onBeforeUnmount(() => {
    if(monacoEditor) {
      ()
    }
  })
 
  return {
    monacoEditorRef,
    createEditor,
    getEditor,
    updateVal,
    updateOptions,
    getOption,
    formatDoc
  }
}

Then call the above useMonacoEditor to encapsulate the editor component

@/components/MonacoEditor/ 

<template>
  <div ref="monacoEditorRef" :style="monacoEditorStyle"></div>
</template>
<script setup lang="ts">
import { useMonacoEditor } from '@/hooks'
import { onMounted, computed, watch } from 'vue'
 
const props = withDefaults(defineProps<{
  width?: string | number,
  height?: string | number,
  language?: string,
  editorOption?: Object,
  modelValue: string
}>(), {
  width: '100%',
  height: '100%',
  language: 'javascript',
  editorOption: () => ({}),
  modelValue: ''
})
 
const emits = defineEmits<{
  (e: 'blue'): void,
  (e: 'update:modelValue', val: string): void
}>()
 
const monacoEditorStyle = computed(() => {
  return { 
    width: typeof  === 'string' ?  :  + 'px', 
    height: typeof  === 'string' ?  :  + 'px'
  }
})
 
const { monacoEditorRef, createEditor, updateVal, updateOptions, getEditor } = useMonacoEditor()
 
onMounted(() => {
  const monacoEditor = createEditor()
  updateMonacoVal()
  monacoEditor?.onDidChangeModelContent(() => {
    emits('update:modelValue', monacoEditor!.getValue())
  })
  monacoEditor?.onDidBlurEditorText(() => {
    emits('blue')
  })
})
 
watch(() => , () => {
  updateMonacoVal()
})
 
function updateMonacoVal(val: string) {
  if(val !== getEditor()?.getValue()) {
    updateVal(val)
  }
}
 
defineExpose({ updateOptions })
</script>

Component usage:

&lt;div class="edit-container"&gt;
  &lt;MonacoEditor ref="MonacoEditRef" v-model="editJson" language="json" /&gt;
&lt;/div&gt;
&lt;script setup lang="ts"&gt;
import MonacoEditor from '@/components/MonacoEditor/'
import { ref } from 'vue'
 
let editJson = ref('')
 
const MonacoEditRef = ref&lt;InstanceType&lt;typeof MonacoEditor&gt;&gt;()
 
//!.updateOptions({ theme: 'vs' }) Call the child component method to modify the configuration&lt;/script&gt;

This is the introduction to this article about the detailed explanation of the tutorial on using Monaco-editor in Vue3. For more related content on using Monaco-editor in Vue3, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!