Next.js中使用react开发嵌入react-monaco-editor代码编辑器的方法(支持语法高亮)

Next.js中使用react开发嵌入react-monaco-editor代码编辑器的方法(支持语法高亮)

安装

(base) PS D:\ai-ui> npm install react-monaco-editor

added 1 package, changed 1 package, and audited 1030 packages in 6s

273 packages are looking for funding
  run `npm fund` for details

1 high severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

定义组件

'use client'

import React, { useEffect, useRef } from 'react';

import * as monaco from 'monaco-editor';

const CodeEditor = ({ code, language, onChange, theme }) => {
    const editorRef = useRef(null);

    useEffect(() => {
        const editor = monaco.editor.create(editorRef.current, {
            value: code,
            language: language,
            theme: theme,
            lineNumbers: 'on',
            lineDecorationsWidth: 10,
            lineNumbersMinChars: 3,
            fontSize: 16,
            fontFamily: 'Consolas, "Courier New", monospace',
            automaticLayout: true,
            minimap: {
                enabled: false,
            },
            scrollBeyondLastLine: false,
            scrollbar: {
                vertical: 'hidden',
                horizontal: 'hidden',
            },
            wordWrap: 'on',
        });

        editor.onDidChangeModelContent(() => {
            onChange(editor.getValue());
        });
        // 组件卸载时销毁编辑器
        return () => {
         editor.dispose();
        };
    }, [theme,language]);

    return <div ref={editorRef} style={{ height: '80%', width: '1000px'}} />;
};

export default CodeEditor;

组件使用:

import {Typography, Flex, Row, Col, Space, Input, message, Button, Dropdown, Select} from 'antd';

// 由于monaco-editor使用了服务端的api,这里需要使用动态导入组件的方式
const CodeEditor = dynamic(() => import('@/app/competitions/doCompetition/normalCoding/CodeMirrorEditor'), {
  ssr: false,
})

export default function Page() {
    const [code, setCode] = useState<string>('');
    const [language, setLanguage] = useState<string>('python');
    const [theme, setTheme] = useState<string>('vs-light');

    const handleCodeChange = (value: string) => {
        setCode(value);
    };

    const handleChangeLanguage = (value: string) => {
        setLanguage(value);
        console.log(`selected ${value}`);
    };

    const handleChangeTheme = (value: string) => {
        setTheme(value)
        console.log(`selected ${value}`);
    };

	//......

 return (
     <>
         
         <Flex vertical={true} style={{width: '100%', backgroundColor: '#dfdffa', borderRadius: '10px'}}>
            <Space wrap={true}>
                <Select defaultValue={'python'}
                    style={{width: 100}}
                    onChange={handleChangeLanguage}
                    options={[
                        {
                            value: 'python',
                            label: 'python',
                        },
                        {
                            value: 'java',
                            label: 'java',
                        },
                        {
                            value: 'c++',
                            label: 'c++',
                        },
                        {
                            value: 'go',
                            label: 'golang',
                        },
                        {
                            value: 'c',
                            label: 'c',
                        },
                        {
                            value: 'javascript',
                            label: 'javascript',
                        },
                        {
                            value: 'json',
                            label: 'json',
                        },
                    ]}
                    />
                <Select defaultValue={'vs-light'}
                    style={{width: 100}}
                    onChange={handleChangeTheme}
                    options={[
                        {
                            value: 'vs-light',
                            label: 'vs-light',
                        },
                        {
                            value: 'vs-dark',
                            label: 'vs-dark',
                        },
                        {
                            value: 'hc-black',
                            label: 'vs-black',
                        },
                    ]}
                    />
            </Space>
            <CodeEditor code={code} language={language} onChange={handleCodeChange} theme={theme}/>
            <pre>{"以下是执行代码的结果:"}</pre>
        </Flex>
   </>
 )   


效果:
在这里插入图片描述

注意导入组件方式要用动态方式

如果使用普通的导入方式,虽然开发环境不会报错,但是构建时会提示错误ReferenceError: window is not defined


// 由于monaco-editor使用了服务端的api,这里需要使用动态导入组件的方式
const CodeEditor = dynamic(() => import('@/app/competitions/doCompetition/normalCoding/CodeMirrorEditor'), {
  ssr: false,
})
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值