自用vue+nuxtJs+vue-monaco制作Monaco Editor编辑器

前言

有小bug;后续写个不用vue-monaco

一、版本

image

二、使用前配置

按插件作者说明下载
image

1.插件注册文件

image

2.nuxt.config.js

实现下方四种语言的自动补全
image

三、使用

<template>
  <div class="warp">
    <monaco-editor
      ref="monacoEditor"
      v-model="value"
      :original="original"
      :options="options"
      :language="language"
      :theme="theme"
      :automatic-layout="automaticLayout"
      :diff-editor="diffEditor"
      class="monacoEditor"
      @editorWillMount="editorWillMount"
      @editorDidMount="editorDidMount"
      @change="monacoChange"
    />
  </div>
</template>
<script>
import MonacoEditor from 'vue-monaco'
export default {
  components: {
    MonacoEditor,
  },
  data() {
    return {
      value: '', // 当前数据
      original: '', // diff开启时,旧数据
      diffEditor: false, // diff功能
      language: 'consoleBoardLanguage', // 语言
      automaticLayout: true, // 自动布局
      theme: 'myCoolTheme', // 主题 默认:vs,vs-dark,hc-black
      // 其它配置
      options: {
        roundedSelection: false, // 右侧不显示编辑器预览框
        contextmenu: true, // 上下文菜单(右键菜单)
        renderWhitespace: 'all', // 启用空白呈现
        formatOnType: true, // 类型格式化
        formatOnPaste: true, // 复制格式化
        foldingStrategy: 'indentation', // 代码可分小段折叠
        folding: true, // 是否启用代码折叠
        readOnly: false, // 只读
        autoIndent: true, // 自动缩进
        automaticLayout: true, // 自适应布局
        wordWrap: true, // 自动换行
        fontSize: 14,
        tabSize: 2, // tab 缩进长度
        renderSideBySide: true, // 行内比较
      },
      monaco: null, // 因为插件bug,用于存放monaco
    }
  },
  methods: {
    // 编辑器挂载之前发生的事件
    editorWillMount(monaco) {
      this.monaco = monaco
      // 可用于注册自定义语言、注册自定义皮肤样式、代码提示补全
      // 注册自定义语言ID
      monaco.languages.register({
        id: 'consoleBoardLanguage',
      })
      //
      monaco.languages.setMonarchTokensProvider('consoleBoardLanguage', {
        tokenizer: {
          root: [
            [/\[error.*/, 'custom-error'],
            [/\[warn.*/, 'custom-warn'],
            [/\[success.*/, 'custom-success'],
            [/\[表达式正确.*/, 'custom-success'],
          ],
        },
      })
      // 注册自定义皮肤样式
      monaco.editor.defineTheme('myCoolTheme', {
        base: 'vs', // 默认皮肤
        inherit: true, // 是否继承 base 设定的原始皮肤样式
        rules: [
          // 规则,token为自定义语言时设置的值
          { token: 'custom-error', foreground: 'ff0000', fontStyle: 'bold' },
          { token: 'custom-warn', foreground: 'FFA500' },
          { token: 'custom-success', foreground: '008800' },
        ],
        colors: {
          // 全局颜色
          'editor.foreground': '#000000',
          'editor.background': '#EDF9FA',
          'editorCursor.foreground': '#8B0000',
          'editor.lineHighlightBackground': '#0000FF20',
          'editorLineNumber.foreground': '#008800',
          'editor.selectionBackground': '#88000030',
          'editor.inactiveSelectionBackground': '#88000015',
        },
      })
      // 代码提示补全
      const API = [
        {
          label: 'success',
          detail: '成功',
          documentation: '成功',
          insertText: '[success]:',
          command: {
            id: 'editor.action.formatDocument', // 内置action详情见附录
            title: '选中这个建议选项后,触发格式化操作'
            // id: 'actions.find',
            // title: '选中这个建议选项后,触发查询',
          },
        },
        {
          label: 'focus()',
          detail: '焦点定位的方法',
          documentation: '焦点定位的方法',
          tags: [monaco.languages.CompletionItemTag.Deprecated],
        },
        {
          label: 'newFocus()',
          detail: '焦点定位的方法',
          documentation: '焦点定位的方法',
        },
      ]
      // 第一个参数为语言ID
      monaco.languages.registerCompletionItemProvider('consoleBoardLanguage', {
        // model:当前model position:当前光标的位置 context:自动完成的上下文
        provideCompletionItems(model, position, context) {
          const word = model.getWordUntilPosition(position) // 获取单词的开始位置
          const range = {
            // 开始位置等于结束位置,那么就是插入操作,否则就是替换操作。
            startLineNumber: position.lineNumber, // 开始行数
            endLineNumber: position.lineNumber, // 结束行数
            startColumn: word.startColumn, // 开始列数
            endColumn: word.endColumn, // 结束列数
          }
          return {
            suggestions: API.map((item) => {
              return {
                label: item.label, // 控制每个选项显示的文本,一个字符串
                detail: item.detail, // 选项的详情,一个字符串
                kind: monaco.languages.CompletionItemKind.Function, // 选项的类型,决定了选项的图标,一个枚举值,详情看附录
                documentation: item.documentation, // 选项的详细描述,一个字符串或markdown
                insertText: item.insertText || item.label, // 最后插入的文本
                tags: item.tags || null, // 设置为 [monaco.languages.CompletionItemTag.Deprecated] 后,选项会显示横线,表示不推荐,或废弃。
                command: item.command || null, // 选择后,自动执行内置的action或command操作
                // range, // 文本要替换的区间,默认是从单词的开始位置(TextDocument.getWordRangeAtPosition)到当前光标的位置。
                additionalTextEdits: [
                  // 追加内容
                  {
                    range,
                    text: `// 追加注释` + '\n', // 内容
                    forceMoveMarkers: true, // true => if `range` is collapsed, all markers at the position will be moved.
                  },
                ],
              }
            }),
          }
        },
      })
    },
    //  编辑器挂载时发生从事件
    editorDidMount(editor) {
      // 可用于注册右键菜单、设置Marker(没用到)
      // Monaco Editor中菜单项的专业术语叫做Action
      const monaco = this.monaco
      editor.addAction({
        id: 'print-console', // action 的唯一id,需要独一无二,不与其他重复
        label: '打印console', // 菜单名称
        keybindings: [
          // 哪些组合键可以触发,右键提示数组最后一项
          monaco.KeyMod.CtrlCmd | monaco.KeyCode.F10,
          // chord为两个组合 ctrl+I ctrl+O
          monaco.KeyMod.chord(
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_I,
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_O
          ),
        ],
        contextMenuGroupId: 'navigation', // 控制操作是否应显示在上下文菜单中以及显示位置 navigation:最前面  insert:自定义取名
        contextMenuOrder: 1.5, // 菜单项的排序权重 越小,越靠前
        run(ed) {
          // 执行函数
          console.log('23333')
          return null
        },
      })
    },
    // 当编辑器内容发生变更触发事件
    monacoChange(newValue, event) {},
    // 所有内置方法
    allMethods() {
      this.$refs.monacoEditor.getEditor()
      this.$refs.monacoEditor.getModifiedEditor()
      this.$refs.monacoEditor.getOriginalEditor()
      this.$refs.monacoEditor.focus()

      // 该方法有bug
      this.$refs.monacoEditor.getMonaco() 
    },
  },
}
</script>
<style lang="scss" scoped>
.warp {
  height: 100%;
  width: 100%;
}
.monacoEditor {
  height: calc(100% - 26px);
  width: calc(100% - 4px);
}
</style>

四、插件bug

getMonaco() 返回值错误,作者也建议弃用了
image

五、附录

1.kind 提示图标类型

image

2.默认action

// 一堆,自己看
console.log(this.$refs.monacoEditor.getEditor()._actions)
posted @ 2022-12-28 17:17  暗鸦08  阅读(503)  评论(0编辑  收藏  举报