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

相关推荐
John_ToDebug10 分钟前
Chrome 浏览器前端与客户端双向通信实战
前端·c++·chrome
要加油哦~15 分钟前
CSS | transition 和 transform的用处和区别
前端·css
小鱼人爱编程26 分钟前
现代大前端是如何编码的?
android·前端·flutter
神仙别闹29 分钟前
基于Java+VUE+MariaDB实现(Web)仿小米商城
java·前端·vue.js
袁煦丞38 分钟前
低成本私有云存储方案Nas-Cab:cpolar实验室第508次成功挑战
前端·程序员·远程工作
小公主39 分钟前
「前端必备」Flex 布局全解析:从入门到深度计算,搞懂弹性盒子!
前端·css
江城开朗的豌豆1 小时前
前端性能救星!用 requestAnimationFrame 丝滑渲染海量数据
前端·javascript·面试
江城开朗的豌豆1 小时前
src和href:这对'双胞胎'属性,你用对了吗?
前端·javascript·面试
江城开朗的豌豆1 小时前
forEach遇上await:你的异步代码真的在按顺序执行吗?
前端·javascript·面试
万少1 小时前
HarmonyOS Next 弹窗系列教程(3)
前端·harmonyos·客户端