开源可视化引擎 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的集成和使用。

相关推荐
September_ning5 小时前
React.lazy() 懒加载
前端·react.js·前端框架
晴天飛 雪5 小时前
React 守卫路由
前端框架·reactjs
web行路人5 小时前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
Thanks_ks6 小时前
探索计算机互联网的奇妙世界:从基础到前沿的无尽之旅
物联网·云计算·区块链·tcp/ip协议·计算机互联网·万维网·未来科技
一ge科研小菜鸡8 小时前
React前端框架:现代网页开发的基石(附带构建简单任务管理应用案例代码)
前端框架
熊的猫8 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
徐嵌8 小时前
STM32项目---畜牧定位器
c语言·stm32·单片机·物联网·iot
Acrelhuang9 小时前
安科瑞5G基站直流叠光监控系统-安科瑞黄安南
大数据·数据库·数据仓库·物联网
jjyangyou9 小时前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
前端青山17 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js