monaco-editor的基本使用

19,281 阅读3分钟

一. 文件调用示例

1. 安装package包

"monaco-editor": "^0.24.0",
"monaco-editor-webpack-plugin": "^3.1.0",

请注意安装包的版本号

执行shell命令

npm install --save-dev monaco-editor
npm install --save-dev monaco-editor-webpack-plugin

2.配置vue.coinfig.js

在vue.coinfig.js中增加如下配置:

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');

module.exports = {
  lintOnSave: false,  
  configureWebpack: {
    plugins: [
      // 配置JS在线代码编辑器monaco-editor的辅助文件
      new MonacoWebpackPlugin(),
    ],
  },
};

3. 调用示例

<template>
  <div>
    <div ref="codeContainer" class="coder-editor"></div>
  </div>
</template>

<script>
import * as monaco from 'monaco-editor';
export default {
  
  data() {
    return {
      monacoEditor: null, // 语言编辑器
    }
  },

  mounted(){
    this.init()
  },

  methods: {
    init(){
      if(this.$refs.codeContainer){
        // 初始化编辑器,确保dom已经渲染
        this.monacoEditor = monaco.editor.create(this.$refs.codeContainer, {
            value: '', // 编辑器初始显示文字
            language: 'json', // 语言
            automaticLayout: true, // 自动布局
            theme: 'vs', // 官方自带三种主题vs, hc-black, or vs-dark
            minimap: { // 关闭小地图
              enabled: false,
            },
            lineNumbers: 'off', // 隐藏控制行号
        });
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.coder-editor{
  width: 100%;
  height: 160px;
  border: 1px solid rgba(0, 0, 0, 0.08);
}
</style>

二. 属性说明

{
    value: '', // 编辑器初始显示文字
    language: 'javascript', // 语言javascript | json
    automaticLayout: true, // 自动布局
    theme: 'vs', // 官方自带三种主题vs, hc-black, or vs-dark
    foldingStrategy: 'indentation', // 代码可分小段折叠
    overviewRulerBorder: false, // 不要滚动条的边框
    lineNumbers: 'off', // 控制行号的出现on | off
    scrollbar: { // 滚动条设置
      verticalScrollbarSize: 4, // 竖滚动条
      horizontalScrollbarSize: 6, // 横滚动条
    },
    readOnly: false, // 是否只读 Defaults to false | true
    minimap: { // 关闭小地图
      enabled: false,
    },
    cursorStyle: 'line', // 光标样式
    automaticLayout: false, // 自动布局
    fontSize: 14, // 字体大小
    tabSize: 2, // tab缩进长度
    autoIndent: true, // 自动布局
}

支持的语言类型

在项目的node_modules/monaco-editor/min/vs/basic-languages目录下能看到支持的语言类型:

image.png

三. 常用事件

销毁编辑器

this.monacoEditor.dispose();

实时获取编辑器的值

this.monacoEditor.onDidChangeModelContent(() => {
  this.monacoEditor.getValue() // 获取编辑器中的语句
})

设置编辑器的值

this.monacoEditor.setValue(newValue)

在编辑器中用波浪线标出错误提示

const model = this.monacoEditor.getModel()      
monaco.editor.setModelMarkers(model, 'json', [{ // json为语言类型
  startLineNumber: 2,
  endLineNumber: 2,
  startColumn: 1,
  endColumn: 10,
  severity: monaco.MarkerSeverity.Error,
  message: `语法错误`,
}])

在初始化编辑器后设置错误提示,设置成功后,输入错误的语法代码,提示效果如下:

image.png

获取语法错误列表

monaco.editor.getModelMarkers({})

在需要处理错误信息时,调用上述方法,可获取错误列表,返回一个数组,数组内容展开如下:

image.png

如果无语法错误,返回[]

在使用的过程中,发现事件getModelMarkers返回所有的语法错误数组,假如第一次操作时errors.length > 0, 修改语法后,这次的错误数组条数应为0,但是返回的还是第一次的语法错误数组。

经过实践,用以下方式更好:

monaco.editor.onDidChangeMarkers(([uri]) => {
  const markers = monaco.editor.getModelMarkers({resource: uri})
  // markers是返回的错误信息数组,可赋值给需要判断语法错误的关键词,如this.coderErrors = markers
}

能实时监听语法变更,统计语法错误信息。

其它事件

editor.setValue('console.log("Hello world!");');    //设置值
editor.getValue();  //获取值

editor.getSelection();  //获取选中的行信息

editor.getModel().getLineContent(1);    //获取某一行的内容
editor.getModel().getLinesContent();    //获取每一行的内容

monaco.editor.setTheme('vs-dark');      //设置主题

editor._configuration._rawOptions.language  //获取编辑器当前语言(初始化值)
editor.getModel().getLanguageId()           //动态(已改变编辑器语言)

//改变属性
editor.updateOptions({
  //关闭行号
  lineNumbers: "off"
});

//内容改变事件
editor.onDidChangeModelContent(function(e){
  console.log(e);
  console.log(editor.getValue());
});

//添加按键监听
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S, function () {
  console.log('Ctrl + S 保存')
})

editor.trigger('a', 'editor.action.formatDocument') //触发:格式化文档,更多支持项:editor._actions

//渲染代码得到HTML
monaco.editor.colorize('console.log("Hello world!");', 'javascript').then(function (data) {
    console.log(data);
});

//渲染节点代码
<pre id="code" data-lang="javascript" style="width:500px;">console.log("Hello world!");</pre>
monaco.editor.colorizeElement(document.getElementById('code'));

四. 报错解决

2022年2月16日更新:

在新的项目按以上流程引入组件时,发现出现以下报错:

 error  in ./node_modules/monaco-editor/esm/vs/language/css/monaco.contribution.js

Module parse failed: Unexpected token (29:15)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| // src/language/css/monaco.contribution.ts
| var LanguageServiceDefaultsImpl = class {
>   _onDidChange = new monaco_editor_core_exports.Emitter();
|   _options;
|   _modeConfiguration;

image.png

查了一圈,发现是版本对应问题,其中monaco-editor和monaco-editor-webpack-plugin的版本要对应,不然会报错。 重新安装了文件包,指定对应版本:

npm install --save-dev monaco-editor@0.24.0
npm install --save-dev monaco-editor-webpack-plugin@3.1.0

再次启动服务,成功启动。

更多属性设置参考: www.jianshu.com/p/0c9fc9267…