• vue3+vite使用monaco-editor编辑器


    vue3+vite使用monaco-editor编辑器

    1.安装

    "monaco-editor": "^0.34.0",这个是package.json中的版本

    npm install monaco-editor
    
    • 1

    2.在vite.config.js中配置

       // 强制预构建插件包
       optimizeDeps: {
        include: [
          `monaco-editor/esm/vs/language/json/json.worker`,
          `monaco-editor/esm/vs/language/css/css.worker`,
          `monaco-editor/esm/vs/language/html/html.worker`,
          `monaco-editor/esm/vs/language/typescript/ts.worker`,
          `monaco-editor/esm/vs/editor/editor.worker`
        ], 
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.组件封装与使用

    1. monacoEditor.vue组件
       <template>
         <div ref="codeEditBox" class="codeEditBox">div>
       template>
       
       <script lang="ts">
       import { defineComponent, onBeforeUnmount, onMounted, ref, watch } from 'vue'
       import { editorProps } from './monacoEditorType'
       import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
       import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
       import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
       import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
       import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
       import * as monaco from 'monaco-editor'
       
       export default defineComponent({
         name: 'monacoEditor',
         props: editorProps,
         emits: ['update:modelValue', 'change', 'editor-mounted'],
         setup(props, { emit }) {
           self.MonacoEnvironment = {
             getWorker(_: string, label: string) {
               if (label === 'json') {
                 return new jsonWorker()
               }
               if (['css', 'scss', 'less'].includes(label)) {
                 return new cssWorker()
               }
               if (['html', 'handlebars', 'razor'].includes(label)) {
                 return new htmlWorker()
               }
               if (['typescript', 'javascript'].includes(label)) {
                 return new tsWorker()
               }
               return new EditorWorker()
             },
           }
           let editor: monaco.editor.IStandaloneCodeEditor
           const codeEditBox = ref()
       
           const init = () => {
             monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
               noSemanticValidation: true,
               noSyntaxValidation: false,
             })
             monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
               target: monaco.languages.typescript.ScriptTarget.ES2020,
               allowNonTsExtensions: true,
             })
       
             editor = monaco.editor.create(codeEditBox.value, {
               value: props.modelValue,
               language: props.language,
               theme: props.theme,
               ...props.options,
             })
       
             // 监听值的变化
             editor.onDidChangeModelContent(() => {
               const value = editor.getValue() //给父组件实时返回最新文本
               emit('update:modelValue', value)
               emit('change', value)
             })
       
             emit('editor-mounted', editor)
           }
           watch(
             () => props.modelValue,
             newValue => {
               if (editor) {
                 const value = editor.getValue()
                 if (newValue !== value) {
                   editor.setValue(newValue)
                 }
               }
             }
           )
       
           watch(
             () => props.options,
             newValue => {
               editor.updateOptions(newValue)
             },
             { deep: true }
           )
       
           watch(
             () => props.language,
             newValue => {
               monaco.editor.setModelLanguage(editor.getModel()!, newValue)
             }
           )
       
           onBeforeUnmount(() => {
             editor.dispose()
           })
       
           onMounted(() => {
             init()
           })
       
           return { codeEditBox }
         },
       })
       script>
       
       <style lang="scss" scoped>
       .codeEditBox {
         width: v-bind(width);
         height: v-bind(height);
       }
       style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    1. monacoEditorType.ts类型定义文件
       import { PropType } from 'vue'
       
       export type Theme = 'vs' | 'hc-black' | 'vs-dark'
       export type FoldingStrategy = 'auto' | 'indentation'
       export type RenderLineHighlight = 'all' | 'line' | 'none' | 'gutter'
       export interface Options {
         automaticLayout: boolean // 自适应布局
         foldingStrategy: FoldingStrategy // 折叠方式  auto | indentation
         renderLineHighlight: RenderLineHighlight // 行亮
         selectOnLineNumbers: boolean // 显示行号
         minimap: {
           // 关闭小地图
           enabled: boolean
         }
         readOnly: boolean // 只读
         fontSize: number // 字体大小
         scrollBeyondLastLine: boolean // 取消代码后面一大段空白
         overviewRulerBorder: boolean // 不要滚动条的边框
       }
       
       export const editorProps = {
         modelValue: {
           type: String as PropType<string>,
           default: null,
         },
         width: {
           type: [String, Number] as PropType<string | number>,
           default: '100%',
         },
         height: {
           type: [String, Number] as PropType<string | number>,
           default: '100%',
         },
         language: {
           type: String as PropType<string>,
           default: 'javascript',
         },
         theme: {
           type: String as PropType<Theme>,
           validator(value: string): boolean {
             return ['vs', 'hc-black', 'vs-dark'].includes(value)
           },
           default: 'vs-dark',
         },
         options: {
           type: Object as PropType<Options>,
           default: function () {
             return {
               automaticLayout: true,
               foldingStrategy: 'indentation',
               renderLineHighlight: 'all',
               selectOnLineNumbers: true,
               minimap: {
                 enabled: true,
               },
               readOnly: false,
               fontSize: 16,
               scrollBeyondLastLine: false,
               overviewRulerBorder: false,
             }
           },
         },
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    1. 在父组件中使用
       <script lang="ts" setup>
       import * as monaco from 'monaco-editor'
       const value = ref('let a = 234')
       const language = ref('javascript')
       const editorMounted = (editor: monaco.editor.IStandaloneCodeEditor) => {
         console.log('editor实例加载完成', editor)
       }
       script>
       
       <template>
         <div class="container">
           <monacoEditor
             v-model="value"
             :language="language"
             width="800px"
             height="500px"
             @editor-mounted="editorMounted"
           >monacoEditor>
         div>
       template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    常用的国际物流运输方式有哪些
    IDEA创建完Maven工程后,右下角一直显示正在下载Maven插件
    布隆过滤器的原理
    springcloud五大核心部件
    abp(net core)+easyui+efcore实现仓储管理系统——供应商管理升级之下(六十四)
    避坑:使用torchvision.transforms.functional.adjust_gamma进行gamma变换时需注意输入数据的类型
    ACL 2019 - AMR Parsing as Sequence-to-Graph Transduction
    真正解决jellyfin硬解码转码
    七天学会C语言-第二天(数据结构)
    Hadoop上传文件到hdfs中
  • 原文地址:https://blog.csdn.net/weixin_44440116/article/details/126843676