开源可视化引擎 Meta2d.js 实战 - 解析自定义格式数据1 - 集成monaco编辑器

在开发一个在页面上提供输入并保存js代码的编辑器功能时,考查了多个在线编辑器均不满意。因为在考察时,会不由自主的将这些编辑器和VSCode进行对比。了解到monaco编辑器其实是VSCode的网页版本时,马上决定就是它了。

先看看集成后的效果:

官网的文档api太多,短时间是很难了解到一个大概。又搜看了多篇 monaco 的安装和使用文章,居然没有一篇能够完整在本地正常运行的。无奈只能多次尝试,现在把集成要点说明如下,希望可以帮助需要的同学少走点弯路。

一、monaco 安装

本地环境: mbp m1 macos14 + vscode1.84.2 + npm9.5.1 + node18.16 + vue3.3.8

csharp 复制代码
yarn add monaco-editor

或者

npm install monaco-editor

二、monaco 配置

我们只需要做到一点即可:在全局对象 Window 中定义一个 monaco 运行时所需要的一个属性 MonacoEnvironment 并定义 getWorker 方法,根据编辑器的用途,定义其内容,如下:

typescript 复制代码
import { boot } from 'quasar/wrappers';
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';

// more info on params: https://v2.quasar.dev/quasar-cli/boot-files
export default boot(async () => {
  self.MonacoEnvironment = {
    getWorker(_, label) {
      if (label === 'json') {
        return new jsonWorker();
      }
      if (['css', 'scss', 'less'].includes(label)) {
        return new cssWorker();
      }
      if (['html', 'handlebars', 'razor'].includes(label)) {
        return new htmlWorker();
      }
      if (['typescript', 'javascript', 'ts', 'js'].includes(label)) {
        return new tsWorker();
      }
      return new EditorWorker();
    },
  };
});

上面的代码是quasar框架中,在系统启动时执行这段代码的一个写法。 getWorker方法内部是根据不同的label的值,来调用不同的解析器。

typescript 复制代码
self.MonacoEnvironment

self就是代表Window对象。本质上其实就是定义了一个名为 MonacoEnvironment 的对象,在其中定义了getWorker方法。monaco编辑器在运行时,会去全局对象Window中寻找 MonacoEnvironment 对象,并调用 getWorker 方法来解析和处理编辑器内的代码。

三、使用

3.1 声明

在模板中,必须给定一个初始高度,比如 30vh。

vue 复制代码
模板中
<div ref="codeEditBox" :style="{ height: height }" />

script中
// div的引用
const codeEditBox = ref();
// 声明一个编辑器对象
let editor: monaco.editor.IStandaloneCodeEditor;

3.2 初始化

typescript 复制代码
interface IProps {
  modelValue?: string;
  language?: string;
  theme?: string;

  // 编辑器区域高度,不包括窗口的header、footer
  height?: string;
}

const props = withDefaults(defineProps<IProps>(), {
  modelValue: '',
  language: 'javascript',
  theme: 'vs-dark',
  height: '30vh',
});

function init(initValue = '') {
  visible.value = true;
  if (initValue !== '') {
    value.value = initValue;
  }

  console.debug('创建 monaco 编辑器');
  monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: true,
    noSyntaxValidation: false
  })
  monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES2020,
    allowNonTsExtensions: true
  })

  editor = monaco.editor.create(codeEditBox.value, {
    value: value.value,
    language: props.language,
    theme: props.theme,
    foldingStrategy: 'indentation',
    automaticLayout: true,
    contextmenu: true,
    minimap: {
      enabled: false,
    },
    scrollBeyondLastLine: false,
    overviewRulerBorder: false
  })

  // 监听值的变化
  editor.onDidChangeModelContent(() => {
    const value = editor.getValue() //给父组件实时返回最新文本
    emit('update:modelValue', value)
  })


  emit('editor-mounted', editor)
  visible.value = false;
}
  

相关api的详细说明,可以去官网查看。不过有一个功能点比较实用 - 格式化

当我们通过编辑器打开输入的代码后,会发现这些代码是在一行的,居然没有格式化输出!这对于天天使用vscode+prettier的我们来说,无疑有点抓狂。研究了官网api文档,编写一个功能函数:

typescript 复制代码
// 格式化代码,如果在init方法后调用,则需要增加100ms延时
function formatCode() {
  if (editor) {
    const range = editor.getModel()?.getFullModelRange();
    editor.getAction('editor.action.formatDocument')?.run(range);
    visible.value = false;
  }
}

至此,就完成了monaco的集成和使用。

相关推荐
数字新视界20 分钟前
信创机房动环监控的核心功能与智能运维管理实践
大数据·物联网·信息可视化·信息与通信·一体化机柜
蓝策电子1 小时前
地下停车场室内定位系统部署指南:蓝牙AoA技术落地实践
物联网
Quanqiucard2 小时前
四轮巡检机器人物联网卡怎么选?5 条硬指标 + 4 重干扰
物联网·机器人
权球物联分享物联网连接服务2 小时前
全景监控怎么联网?6 条选物联网卡硬指标 + 3 个流量量级
物联网
K成长日志2 小时前
BLE Host层L2CAP -- 状态机
物联网·网络协议·无线通信·蓝牙·iot·ble
小莞尔2 小时前
【51单片机】【protues仿真】基于51单片机超声波测距仪系统
c语言·单片机·嵌入式硬件·物联网·51单片机
星恒讯工业路由器3 小时前
工业网关固件升级:远程OTA支持与防变砖机制详解
网络·物联网·工业网关·固件升级·远程ota·防变砖机制·双系统备份
辛迪聊物业数字化3 小时前
中小物业SaaS系统架构设计:从收费、巡检到IoT对接的落地实践
物联网·系统架构
Yiran_G3 小时前
ZigBee通信正常,数据却是错的?嵌入式开发中的数据链路排查
网络·嵌入式硬件·物联网·智能家居
honsor3 小时前
ModbusTCP、SNMP、HTTP 怎么选?以太网温湿度变送器协议选型实战
网络·物联网·网络协议·tcp/ip·http