一、老规矩先上效果图
二、安装依赖
pnpm install monaco-editor@0.45.0
pnpm install react-monaco-editor@0.55.0
pnpm install monaco-editor-webpack-plugin@7.1.0
三、配置代码高亮
Umi -- 在config.ts或者.umirc.ts中配置以下代码
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
export default defineConfig({
...
chainWebpack(memo) {
memo.plugin('monaco-editor').use(MonacoWebpackPlugin, [
{
// 支持代码高亮显示的语言
languages: ['json','java','python','sql','mysql','html','css','less','scss','javascript','typescript','xml'],
},
]);
},
});
React -- 在webpack.config.js文件中配置以下代码
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
plugins: [
new MonacoWebpackPlugin({
languages: ['json','java','python','sql','mysql','html','css','less','scss','javascript','typescript','xml'],
})
]
};
languages支持语言
'abap' | 'apex' | 'azcli' | 'bat' | 'cameligo' | 'clojure' | 'coffee' | 'cpp' | 'csharp' | 'csp' |
'css' | 'dockerfile' | 'fsharp' | 'go' | 'graphql' | 'handlebars' | 'html' | 'ini' | 'java' | 'javascript' |
'json' | 'kotlin' | 'less' | 'lua' | 'markdown' | 'mips' | 'msdax' | 'mysql' | 'objective-c' | 'pascal' |
'pascaligo' | 'perl' | 'pgsql' | 'php' | 'postiats' | 'powerquery' | 'powershell' | 'pug' | 'python' | 'r' |
'razor' | 'redis' | 'redshift' | 'restructuredtext' | 'ruby' | 'rust' | 'sb' | 'scheme' | 'scss' | 'shell' |
'solidity' | 'sophia' | 'sql' | 'st' | 'swift' | 'tcl' | 'twig' | 'typescript' | 'vb' | 'xml' | 'yaml'
四、上代码
这是我配合antd封装的编辑器组件,可以适用于表单元素,也可以独立使用
import { Card, Select, Space } from 'antd';
import { useState } from 'react';
import MonacoEditor from 'react-monaco-editor';
import '../index.less';
type MonacoEditorProps = {
value?: string;
onChange?: (value: string) => void;
width?: string | number;
height?: string | number;
theme?: 'vs' | 'vs-dark' | 'hc-black' | 'hc-light'; // 主题
select?: boolean; //开启语言选择器
language?:
| 'json'
| 'java'
| 'python'
| 'sql'
| 'mysql'
| 'html'
| 'javascript'
| 'typescript'
| 'xml'; // 语言
};
export default (props: MonacoEditorProps) => {
const {
width = '100%',
height = '400',
value,
theme = 'vs',
select = false,
language = 'json',
onChange,
} = props;
const [languageValue, setLanguageValue] = useState(language);
const options: any = {
selectOnLineNumbers: true,
roundedSelection: false,
readOnly: false, // //是否只读 取值 true | false
cursorStyle: 'line',
automaticLayout: false, // 自动布局
};
const extraSelect = (
<Space>
<Select
disabled={!select}
bordered={false}
popupMatchSelectWidth={120}
defaultValue={languageValue}
onChange={(e) => setLanguageValue(e)}
options={[
{ label: 'json', value: 'json' },
{ label: 'java', value: 'java' },
{ label: 'python', value: 'python' },
{ label: 'sql', value: 'sql' },
{ label: 'mysql', value: 'mysql' },
{ label: 'html', value: 'html' },
{ label: 'javascript', value: 'javascript' },
{ label: 'typescript', value: 'typescript' },
{ label: 'xml', value: 'xml' },
]}
/>
</Space>
);
return (
<Card
title={extraSelect}
className={
theme === 'hc-black' || theme === 'vs-dark'
? 'card-theme-black'
: 'card-theme-light'
}
headStyle={{ minHeight: 40 }}
bodyStyle={{ padding: 0 }}
>
<MonacoEditor
{...props}
width={width}
height={height}
value={value ?? `// ${languageValue}`}
theme={theme}
language={languageValue}
options={options}
onChange={(newValue) => onChange?.(newValue)}
/>
</Card>
);
};
// 组件样式 (黑暗模式/普通模式)
.card-theme-black {
background-color: #222222 !important;
.ant-card-head {
border-bottom: 2px solid black !important;
.ant-select-selection-item {
color: #cccccc !important;
}
.ant-select-arrow > .anticon {
color: #cccccc !important;
}
}
}
.card-theme-light {
.ant-card-head {
border-bottom: 2px solid #eeeeee !important;
}
}