最近因为需要实现一个在线代码的需求,所以研究了相关的内容,其中最主要的就是编辑器相关的内容
对于 monaco 编辑器的选择,我使用了 @monaco-editor/react
库
import type { EditorProps, OnChange, OnMount } from '@monaco-editor/react'
import { Editor as MonacoEditor } from '@monaco-editor/react'
import { useDebounceFn } from 'ahooks'
import { Spin } from 'antd'
import { FC, useState } from 'react'
export const CodeEditor: FC<EditorProps> = props => {
const [theme, setTheme] = useState('vs')
// 处理代码修改, args需要做一层透传来完善防抖,避免触发重复构建
const { run: handleChange } = useDebounceFn<OnChange>(
(...args) => {
if (props.onChange) {
props.onChange(...args)
}
},
{
wait: 400,
},
)
return (
<MonacoEditor
loading={<Spin />}
theme={theme}
{...props}
onChange={handleChange}
/>
)
简单的对齐进行了封装使用
在使用 @monaco-editor/react
库,会通过CDN去加载编辑器的资源
但有时候,我们所需要的环境,并不能直接去访问外网,故我们需要将这些资源改变成本地加载
首先我们需要一个公共位置去存放这些资源,如 vite 的 public 文件夹等等
我们需要把 monaco-editor
库下载下来,主要是需要 min/vs 内容,提供给编辑器
其实还有另一种方式,是安装 monaco-editor 库,并引入即可,但之前测试的时候是有问题的,包括 webpack 等等,不太稳定,所以没有选择这种方式
import { loader } from '@monaco-editor/react'
loader.config({
paths: {
// public 下存放 monaco-editor 的路径
vs: '/npm/monaco-editor/min/vs',
},
})
通过这种方式,就可以避免编辑器去加载远程资源了
在在线代码里,我们还需要自定义一些专属的东西,如全局上下文等内容
Monaco Editor (microsoft.github.io)
基本的操作方法可以查看一下官网的案例
主要就是通过 monaco.languages.registerCompletionItemProvider
方法去注册,然后返回规定格式的 suggestion
即可,最后再选择一个触发方式,即 triggerCharacters
。
monaco.languages.registerCompletionItemProvider('javascript', {
provideCompletionItems: (model, position) => {
const range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: model.getWordUntilPosition(position).startColumn,
endColumn: model.getWordUntilPosition(position).endColumn,
}
return {
suggestions: [
{
label: 'test', // 显示的提示内容
kind: monaco.languages.CompletionItemKind.Function, // 用来显示提示内容后的不同的图标
insertText: 'test', // 选择后粘贴到编辑器中的文字
detail: '', // 提示内容后的说明
range: range,
},
],
}
},
triggerCharacters: ['.'],
})
上面代码实现的就是按下 .
时触发提示,并提示出 test
方法