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... 很多很全

相关推荐
百万蹄蹄向前冲1 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5812 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路2 小时前
GeoTools 读取影像元数据
前端
ssshooter3 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友3 小时前
【Node.js】什么是Node.js
javascript·后端·node.js
Jerry3 小时前
Jetpack Compose 中的状态
前端
dae bal4 小时前
关于RSA和AES加密
前端·vue.js
柳杉4 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog4 小时前
低端设备加载webp ANR
前端·算法
LKAI.5 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi