Vue3中使用Monaco-editor的教程详解

 更新时间:2023年11月01日 13:58:40   作者:会说法语的猪  
Monaco-editor,一个vs code 编辑器,需要将其继承到项目,这篇文章主要为大家详细介绍了如何在vue中安装和使用Monaco-editor,有需要的小伙伴可以参考下

Monaco-editor,一个vs code 编辑器,需要将其继承到项目。不说闲话了,直接上代码。 

npm地址:https://www.npmjs.com/package/monaco-editor

中文文档:https://aydk.site/editor/

安装

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

配置

vite.config.ts

import { defineConfig} from 'vite'
 
// vs code 编辑器配置
import monacoEditorPlugin from 'vite-plugin-monaco-editor'
 
// https://vitejs.dev/config/
export default ({ mode }) => {
  return defineConfig({
    plugins: [
      monacoEditorPlugin({
        languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html']
      })
    ]
  })
}

封装

首先先封装个hook如下:

@/hooks/useMonacoEditor.hook.ts 

import * as monaco from 'monaco-editor'
import useCommonStore from '@/store/common'
import { ref, nextTick, onBeforeUnmount } from 'vue'
 
export function useMonacoEditor(language: string = 'javascript') {
  // 编辑器示例
  let monacoEditor: monaco.editor.IStandaloneCodeEditor | null = null
  // 目标元素
  const monacoEditorRef = ref<HTMLElement | null>(null)
 
  // 创建实例
  function createEditor(editorOption: monaco.editor.IStandaloneEditorConstructionOptions = {}) {
    if(!monacoEditorRef.value) return
    monacoEditor = monaco.editor.create(monacoEditorRef.value, {
      // 初始模型
      model: monaco.editor.createModel('', language),
      // 是否启用预览图
      minimap: { enabled: true },
      // 圆角
      roundedSelection: true,
      // 主题
      theme: useCommonStore().mode == 'dark' ? 'vs-dark' : 'vs',
      // 主键
      multiCursorModifier: 'ctrlCmd',
      // 滚动条
      scrollbar: {
        verticalScrollbarSize: 8,
        horizontalScrollbarSize: 8
      },
      // 行号
      lineNumbers: 'on',
      // tab大小
      tabSize: 2,
      //字体大小
      fontSize: 16,
      // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
      autoIndent: 'advanced',
      // 自动布局
      automaticLayout: true,
      ...editorOption
    })
    return monacoEditor
  }
 
  // 格式化
  async function formatDoc() {
    await monacoEditor?.getAction('editor.action.formatDocument')?.run()
  }
 
  // 数据更新
  function updateVal(val: string) {
    nextTick(() => {
      if(getOption(monaco.editor.EditorOption.readOnly)) {
        updateOptions({ readOnly: false })
      }
      monacoEditor?.setValue(val)
      setTimeout(async () => {
        await formatDoc()
      }, 10)
    })
  }
 
  // 配置更新
  function updateOptions(opt: monaco.editor.IStandaloneEditorConstructionOptions) {
    monacoEditor?.updateOptions(opt)
  }
 
  // 获取配置
  function getOption(name: monaco.editor.EditorOption) {
    return monacoEditor?.getOption(name)
  }
 
  // 获取实例
  function getEditor() {
    return monacoEditor
  }
 
  // 页面离开 销毁
  onBeforeUnmount(() => {
    if(monacoEditor) {
      monacoEditor.dispose()
    }
  })
 
  return {
    monacoEditorRef,
    createEditor,
    getEditor,
    updateVal,
    updateOptions,
    getOption,
    formatDoc
  }
}

然后调用上面 useMonacoEditor 封装editor编辑器组件

@/components/MonacoEditor/index.vue 

<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 props.width === 'string' ? props.width : props.width + 'px', 
    height: typeof props.height === 'string' ? props.height : props.height + 'px'
  }
})
 
const { monacoEditorRef, createEditor, updateVal, updateOptions, getEditor } = useMonacoEditor(props.language)
 
onMounted(() => {
  const monacoEditor = createEditor(props.editorOption)
  updateMonacoVal(props.modelValue)
  monacoEditor?.onDidChangeModelContent(() => {
    emits('update:modelValue', monacoEditor!.getValue())
  })
  monacoEditor?.onDidBlurEditorText(() => {
    emits('blue')
  })
})
 
watch(() => props.modelValue, () => {
  updateMonacoVal(props.modelValue)
})
 
function updateMonacoVal(val: string) {
  if(val !== getEditor()?.getValue()) {
    updateVal(val)
  }
}
 
defineExpose({ updateOptions })
</script>

组件使用: 

<div class="edit-container">
  <MonacoEditor ref="MonacoEditRef" v-model="editJson" language="json" />
</div>
<script setup lang="ts">
import MonacoEditor from '@/components/MonacoEditor/index.vue'
import { ref } from 'vue'
 
let editJson = ref('')
 
const MonacoEditRef = ref<InstanceType<typeof MonacoEditor>>()
 
//MonacoEditRef.value!.updateOptions({ theme: 'vs' }) 调用子组件方法修改配置
</script>

到此这篇关于Vue3中使用Monaco-editor的教程详解的文章就介绍到这了,更多相关Vue3使用Monaco-editor内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue全局事件总线$bus安装与应用小结

    Vue全局事件总线$bus安装与应用小结

    这篇文章主要介绍了Vue全局事件总线$bus安装与应用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • vue如何使用vant组件的field组件disabled修改默认样式

    vue如何使用vant组件的field组件disabled修改默认样式

    这篇文章主要介绍了vue如何使用vant组件的field组件disabled修改默认样式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Vue渲染失败的几种原因及解决方案

    Vue渲染失败的几种原因及解决方案

    这篇文章主要介绍了Vue渲染失败的几种原因及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 如何基于vue-cli3.0构建功能完善的移动端架子

    如何基于vue-cli3.0构建功能完善的移动端架子

    这篇文章主要介绍了基于vue-cli3.0构建功能完善的移动端架子,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 前端element-ui两层dialog嵌套遮罩层消失的问题解决办法

    前端element-ui两层dialog嵌套遮罩层消失的问题解决办法

    最近使用vue+elementUI做项目,使用过程中很多地方会用到dialog这个组件,有好几个地方用到了dialog的嵌套,这篇文章主要给大家介绍了关于前端element-ui两层dialog嵌套遮罩层消失的问题解决办法,需要的朋友可以参考下
    2024-08-08
  • 详解vue.js数据传递以及数据分发slot

    详解vue.js数据传递以及数据分发slot

    本篇文章给大家通过代码实例分析了vue.js数据传递以及数据分发slot的相关知识,有这方面兴趣的朋友参考下吧。
    2018-01-01
  • Vue 子组件与数据传递问题及注意事项

    Vue 子组件与数据传递问题及注意事项

    这篇文章主要介绍了Vue子组件与数据传递问题及需要注意事项,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • vue+elementUI实现动态合并数据相同的单元格(可指定合并列)

    vue+elementUI实现动态合并数据相同的单元格(可指定合并列)

    这篇文章主要介绍了vue+elementUI如何实现动态合并数据相同的单元格,文中有详细的代码实例供大家参考,具有一定的参考价值,需要的朋友可以参考下
    2023-07-07
  • vuex5中的Pinia插件机制

    vuex5中的Pinia插件机制

    这篇文章主要介绍了vuex5中的Pinia插件机制,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • Vue3组件不发生变化如何监听pinia中数据变化

    Vue3组件不发生变化如何监听pinia中数据变化

    这篇文章主要给大家介绍了关于Vue3组件不发生变化如何监听pinia中数据变化的相关资料,pinia是Vue的存储库,它允许您跨组件/页面共享状态,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11

最新评论