Vue2使用Monaco Editor编辑器

431 阅读1分钟

背景

使用编辑器对json与xml进行格式化与编辑,由于项目是老项目使用的是Vue2版本,所以版本相当重要,版本容易报错。

安装

我这里安装的版本是0.21.3版本,其他版本都有问题,Vue是2.6.11版本,webpack是4.28.4版本。然后我这里也使用了monaco-editor-webpack-plugin插件,我这里使用的是2.1.0版本。安装方法如下。

npm install monaco-editor@0.21
npm install monaco-editor-webpack-plugin@2 -D

需要注意的是他们两个的版本需要对应好,否则可能会报错,对应版本如下

editorplugin
0.18.*1.7.*
0.19.*1.8.*
0.20.*1.9.*
0.21.*2..
>= 0.22.* <= 0.24.*3..
>= 0.25.* <= 0.28.*4..
0.29.*5..
0.30.*6..
>= 0.31.07..

实现

配置插件,vue.config.js中配置

    // 引入插件
    const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
    
    // 在configureWebpack配置插件
    plugins: [
      new MonacoWebpackPlugin() // 根据自己的情况配置所需要的languages等
    ]

编辑器实现MonacoEditor.vue

<template>
  <div ref="CodeEditor" style="width: 100%; height: 100%;" />
</template>

<script>
import * as monaco from 'monaco-editor'

export default {
  name: 'CodeEditor',
  props: {
    editable: { type: Boolean, default: true },
    language: { type: String, default: 'json' },
    value: { type: String, required: true, default: '' }
  },

  data() {
    return {
      codeEditor: null
    }
  },

  watch: {
    value: function(val) {
      this.updateEditor(val)
    }
  },

  mounted() {
    this.updateEditor(this.value)
  },

  beforeDestroy() {
    this.codeEditor.dispose()
  },

  methods: {

    updateEditor(content) {
      // 未创建则创建
      if (!this.codeEditor) {
        this.codeEditor = monaco.editor.create(this.$refs.CodeEditor, {
          value: '',
          language: this.language,
          roundedSelection: false,
          readOnly: !this.editable,
          theme: 'vs',
          wordWrap: 'wordWrapColumn',
          wordWrapColumn: 80,

          tabSize: 2,
          folding: true, // 是否折叠
          foldingHighlight: true, // 折叠等高线
          foldingStrategy: 'auto', // 折叠方式
          showFoldingControls: 'always', // 是否一直显示折叠
          disableLayerHinting: true, // 等宽优化
          automaticLayout: true, // 自动布局
          scrollBeyondLastLine: false, // 滚动完最后一行后再滚动一屏幕
          colorDecorators: true, // 颜色装饰器
          lineNumbers: 'on', // 行号 取值: "on" | "off" | "relative" | "interval" | function
          lineNumbersMinChars: 5, // 行号最小字符   number

          scrollbar: {
            // Subtle shadows to the left & top. Defaults to true.
            useShadows: false,

            // Render vertical arrows. Defaults to false.
            verticalHasArrows: false,
            // Render horizontal arrows. Defaults to false.
            horizontalHasArrows: false,

            // Render vertical scrollbar.
            // Accepted values: 'auto', 'visible', 'hidden'.
            // Defaults to 'auto'
            vertical: 'auto',
            // Render horizontal scrollbar.
            // Accepted values: 'auto', 'visible', 'hidden'.
            // Defaults to 'auto'
            horizontal: 'auto',

            verticalScrollbarSize: 10,
            horizontalScrollbarSize: 10,
            arrowSize: 10
          },

          // 小地图
          minimap: {
            enabled: false
          }
        })
        this.codeEditor.onDidChangeModelContent(() => {
          this.$emit('input', this.codeEditor.getValue())
        })
      }
      // 修改后将value设置到编辑中
      if (content !== this.codeEditor.getValue()) { this.codeEditor.setValue(content) }

      this.codeEditor.updateOptions({
        readOnly: !this.editable
      })
      // 创建后再次修改language
      const model = this.codeEditor.getModel()
      const language = model.getModeId()
      if (language !== this.language) {
        monaco.editor.setModelLanguage(model, this.language)
      }
    }
  }
}
</script>

使用编辑器

// 导入
import CodeEditor from '@/components/MonacoEdit.vue'

// language选项中可查询官网
<CodeEditor
    v-model="message"
    :language="language"
/>

结语

其他配置及api可自行查阅官网,我这里只是简单实现了我项目中的功能。