Vue3 中集成 Monaco Editor

官网: microsoft.github.io/monaco-edit...

文档地址: microsoft.github.io/monaco-edit...

npm 地址: www.npmjs.com/package/mon...

Vue3 中集成 Monaco Editor

安装

bash 复制代码
npm i monaco-editor

创建一个简单的代码编辑器

本段介绍了如何在项目中引入 Monaco Editor 以及 如何创建一个简单的代码编辑器。

实现效果

实现代码

vue 复制代码
<script setup>
import { ref, onMounted } from 'vue'

// 引入 Monaco Editor
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'

// 引入自定义语言 Monarch
import customLangMonarch from '@/components/editor/custom-lang-monarch'

// 注册自定义语言
monaco.languages.register({ id: 'custom' })
// 设置 Monarch Tokens 提供者
monaco.languages.setMonarchTokensProvider('custom', customLangMonarch)

// 创建对编辑器的引用
const editor = ref()

// 在组件挂载后执行
onMounted(() => {
  // 创建 Monaco Editor 实例
  monaco.editor.create(editor.value, {
    // 设置初始代码值
    value: `// 在此处输入您的语言的源代码...
class MyClass {
  @attribute
  void main() {
    Console.writeln( "Hello Monarch world\n");
  }
}`,
    // 设置语言为自定义语言
    language: 'custom'
  })
})
</script>

<template>
  <div class="editor-container">
    <!-- 将编辑器容器绑定到 ref -->
    <div id="editor" ref="editor"></div>
  </div>
</template>

<style scoped>
.editor-container {
  width: 100%;
  height: 100%;
  padding: 15px;
  background: #ffffff;
}
#editor {
  width: 100%;
  height: 100%;
}
</style>

Monaco Editor的自定义语言定义,使用了Monarch格式。它定义了关键字、类型关键字、运算符、符号等各种语法元素的词法分析规则。注释部分详细说明了各个规则的作用和匹配方式。

js 复制代码
/**
 * 自定义语言定义,参考自 https://microsoft.github.io/monaco-editor/monarch.html
 * (采用 Monarch 格式)
 */
export default {
  // 关键字
  keywords: [
    'abstract', 'continue', 'for', 'new', 'switch', 'assert', 'goto', 'do', 'if', 'private',
    'this', 'break', 'protected', 'throw', 'else', 'public', 'enum', 'return', 'catch', 'try',
    'interface', 'static', 'class', 'finally', 'const', 'super', 'while', 'true', 'false'
  ],

  // 类型关键字
  typeKeywords: ['boolean', 'double', 'byte', 'int', 'short', 'char', 'void', 'long', 'float'],

  // 运算符
  operators: [
    '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=', '&&', '||', '++', '--', '+', '-',
    '*', '/', '&', '|', '^', '%', '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=',
    '%=', '<<=', '>>=', '>>>='
  ],

  // 符号
  symbols: /[=><!~?:&|+\-*\/\^%]+/,

  // 转义字符
  escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,

  // 主要的标记器定义
  tokenizer: {
    root: [
      // 标识符和关键字
      [
        /[a-z_$][\w$]*/,
        {
          cases: {
            '@typeKeywords': 'keyword',
            '@keywords': 'keyword',
            '@default': 'identifier'
          }
        }
      ],
      [/[A-Z][\w\$]*/, 'type.identifier'], // 为了美观显示类名

      // 空白字符
      { include: '@whitespace' },

      // 分隔符和运算符
      [/[{}()\[\]]/, '@brackets'],
      [/[<>](?!@symbols)/, '@brackets'],
      [
        /@symbols/,
        {
          cases: {
            '@operators': 'operator',
            '@default': ''
          }
        }
      ],

      // @ 注解
      [/@\s*[a-zA-Z_\$][\w\$]*/, { token: 'annotation', log: 'annotation token: $0' }],

      // 数字
      [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
      [/0[xX][0-9a-fA-F]+/, 'number.hex'],
      [/\d+/, 'number'],

      // 分隔符:放在数字后面是因为 .\d 浮点数
      [/[;,.]/, 'delimiter'],

      // 字符串
      [/"([^"\\]|\\.)*$/, 'string.invalid'], // 未终止的字符串
      [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }],

      // 字符
      [/'[^\\']'/, 'string'],
      [/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
      [/'/, 'string.invalid']
    ],

    comment: [
      [/[^\/*]+/, 'comment'],
      [/\/\*/, 'comment', '@push'], // 嵌套注释
      ['\\*/', 'comment', '@pop'],
      [/[\/*]/, 'comment']
    ],

    string: [
      [/[^\\"]+/, 'string'],
      [/@escapes/, 'string.escape'],
      [/\\./, 'string.escape.invalid'],
      [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }]
    ],

    whitespace: [
      [/[ \t\r\n]+/, 'white'],
      [/\/\*/, 'comment', '@comment'],
      [/\/\/.*$/, 'comment']
    ]
  }
}

Monaco Editor的API和基本用法

常见的 API

API / 基本用法 描述
monaco.editor.create() 创建一个新的编辑器实例
monaco.editor.setModel() 设置编辑器的数据模型
monaco.editor.getModels() 获取当前所有已创建的编辑器的数据模型
monaco.editor.IStandaloneCodeEditor 表示一个独立的代码编辑器实例
monaco.editor.IModel 表示编辑器的数据模型
monaco.editor.createModel() 创建一个新的编辑器数据模型
editor.setValue(content) 设置编辑器的文本内容
editor.getValue() 获取编辑器的文本内容
editor.onDidChangeModelContent(callback) 监听编辑器内容变化事件
editor.dispose() 销毁编辑器实例
monaco.editor.defineTheme() 定义编辑器主题
monaco.languages.register() 注册新的语言
monaco.languages.setMonarchTokensProvider() 设置 Monarch 语法解析器提供者

下面将常见的几个 API 列举一些使用实例。

基本用法

1. 创建编辑器实例:

通过 monaco.editor.create() 方法创建一个新的编辑器实例,并指定其容器和初始配置。

javascript 复制代码
const editor = monaco.editor.create(document.getElementById('editor-container'), {
    value: 'console.log("Hello, world!")',
    language: 'javascript'
});

2. 设置编辑器内容:

使用 editor.setValue() 方法设置编辑器的文本内容。

javascript 复制代码
editor.setValue('console.log("Hello, world!")');

3. 获取编辑器内容:

使用 editor.getValue() 方法获取编辑器的文本内容。

javascript 复制代码
const content = editor.getValue();

4. 监听编辑器事件:

使用 editor.onDidChangeModelContent() 方法监听编辑器内容变化事件。

javascript 复制代码
editor.onDidChangeModelContent(event => {
    console.log('Editor content changed:', event);
    console.log(editor.getValue()) // 获取更新后的内容
    emits('change', editor.getValue()) // 将更新后的内容暴露出去
});

5. 销毁编辑器实例:

使用 editor.dispose() 方法销毁编辑器实例。

javascript 复制代码
editor.dispose();

创建编辑器的Options

js 复制代码
const editorRef =ref()

onMounted(()=>{
  const editor = monaco.editor.create(editorRef.value, {
    value:"", // 编辑器初始显示内容
    language: "javascript", // 支持语言
    theme:"vs-dark" // 主题
    // .........
	})
})

<div id="editor" ref="editorRef"></div>

控制是否显示缩略图

因为manaco editor 的文档不是特别直观, 所以通过分析 "控制是否显示缩略图" 属性的来探索一下遇到其它问题的学习路径。

  1. 通过文档 microsoft.github.io/monaco-edit... 找到响应的属性
  2. 查看对应属性的描述 Interface IEditorMinimapOptions 或者通过在编辑器中跳转到属性的实现文档ts
  3. 分析各个属性

minimap: IEditorMinimapOptions

js 复制代码
export interface IEditorMinimapOptions {
    /**
     * 是否启用缩略图的渲染。
     * 默认为 true。
     */
    enabled?: boolean;
    /**
     * 控制缩略图的渲染。
     */
    autohide?: boolean;
    /**
     * 控制缩略图在编辑器中的位置。
     * 默认为 'right'。
     */
    side?: 'right' | 'left';
    /**
     * 控制缩略图的渲染模式。
     * 默认为 'actual'。
     */
    size?: 'proportional' | 'fill' | 'fit';
    /**
     * 控制缩略图滑块的渲染。
     * 默认为 'mouseover'。
     */
    showSlider?: 'always' | 'mouseover';
    /**
     * 是否在行上渲染实际文本(而不是颜色块)。
     * 默认为 true。
     */
    renderCharacters?: boolean;
    /**
     * 限制缩略图的宽度,最多渲染一定数量的列。
     * 默认为 120。
     */
    maxColumn?: number;
    /**
     * 缩略图中字体的相对大小。默认为 1。
     */
    scale?: number;
}

options列表

vbnet 复制代码
value
language
theme
readOnly
selectOnLineNumbers: true,
roundedSelection: false,
readOnly: false, // 只读
writeOnly: false,
cursorStyle: 'line', //光标样式
automaticLayout: true, //自动布局
glyphMargin: true, //字形边缘
useTabStops: false,
fontSize: 18, //字体大小
autoIndent: true, //自动布局
//quickSuggestionsDelay: 500,   //代码提示延时

查询 options 的 地址

microsoft.github.io/monaco-edit... 很多很全

相关推荐
计算机学姐10 分钟前
基于微信小程序的调查问卷管理系统
java·vue.js·spring boot·mysql·微信小程序·小程序·mybatis
一颗花生米。3 小时前
深入理解JavaScript 的原型继承
java·开发语言·javascript·原型模式
学习使我快乐013 小时前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio19953 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
勿语&4 小时前
Element-UI Plus 暗黑主题切换及自定义主题色
开发语言·javascript·ui
黄尚圈圈4 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水5 小时前
简洁之道 - React Hook Form
前端
正小安7 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch9 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j