代码在线编辑codemirror在React中使用

初次学习codemirror笔记,下附完整代码

成果图

安装

yarn add codemirror

 引入

import CodeMirror from 'codemirror';
import 'codemirror/lib/codemirror.css'

 

options配置

1.行号

lineNumbers:true//是否显示左侧行号
firstLineNumber: 1//从哪个数字开始计数行。默认值为 1。

2.编码模式

  模式可查看  https://codemirror.net/mode/

import "codemirror/mode/python/python.js";
 
mode: "python", // 要使用的模式//https://codemirror.net/mode/

3.滚动和换行

 lineWrapping: true,//滚动或换行
 scrollbarStyle: null,//滚动条样式,为null时隐藏滚动条

4.主题

//引入主题文件(可选择自己喜欢的)
import 'codemirror/theme/material.css';
import 'codemirror/theme/solarized.css'

//options中配置
theme: 'material',//主题

 5.代码折叠

// 引入
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/foldgutter.js';
import 'codemirror/addon/fold/brace-fold.js';
import 'codemirror/addon/fold/comment-fold.js';
import 'codemirror/addon/fold/indent-fold.js';

//options中配置
// 在行槽中添加行号显示器、折叠器、语法检测器
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"],
foldGutter: true, // 启用行槽中的代码折叠

6.缩进

tabSize: 2, //tab键缩进,默认4
smartIndent: true, // 智能缩进
indentUnit: 2, // 智能缩进单位为2个空格长度
indentWithTabs: true//Whether, when indenting, the first N*tabSize spaces should be replaced by N tabs. Default is false.没看明白😅

7.选中行高亮

//引入
import "codemirror/addon/selection/active-line.js";

options中配置
styleActiveLine: true, // 显示选中行的样式

8.括号匹配以及自动补全

// 括号匹配
import "codemirror/addon/edit/closebrackets.js";
import "codemirror/addon/edit/matchbrackets.js";

//options中配置
matchBrackets: true,	//括号匹配
autoCloseBrackets: true,//括号自动补全

 9.代码提示级自动补全

// 代码提示
import 'codemirror/addon/hint/show-hint.css'; //
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/anyword-hint.js'; // 简单提示,按需引入,spl可引入sql-hint.js

//代码提示自动补全功能
myCodeMirror.on("keypress", function () {//代码补全功能
   myCodeMirror.showHint();
});

//如果未选择提示代码,会默认选中第一个补全代码,emmmm.....
//可在options中配置以下代码,默认不补全,只提示
hintOptions: {
   completeSingle: false//代码自动补全功能不默认补充
},

完整代码

import React, { useEffect, useState } from 'react'
import axios from 'axios';

import CodeMirror from 'codemirror';
import 'codemirror/lib/codemirror.css'
//主题
import 'codemirror/theme/material.css';
import 'codemirror/theme/solarized.css'
// 折叠代码
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/foldgutter.js';
import 'codemirror/addon/fold/brace-fold.js';
import 'codemirror/addon/fold/comment-fold.js';
import 'codemirror/addon/fold/indent-fold.js';

// 代码提示
import 'codemirror/addon/hint/show-hint.css'; //
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/anyword-hint.js'; // 简单提示,按需引入,spl可引入sql-hint.js

import "codemirror/addon/comment/comment.js";
// 高亮
import "codemirror/addon/selection/active-line.js";

// python语言
import "codemirror/mode/python/python.js";

// 括号匹配
import "codemirror/addon/edit/closebrackets.js";
import "codemirror/addon/edit/matchbrackets.js";

import 'codemirror/addon/lint/lint.js'
import 'codemirror/addon/lint/javascript-lint.js'

import Style from './OnlineEdit.module.css'
import { Button } from 'antd';

let myCodeMirror;
export default function OnlineEdit() {
    const [submitResult, setSubmitResult] = useState('')
    // 初始化编辑器
    useEffect(() => {
        const textArea = document.getElementById("editor");
        myCodeMirror = CodeMirror.fromTextArea(textArea, {
            theme: 'material',//主题
            lineNumbers: true,//显示行号
            firstLineNumber: 1,//行号从几开始,默认1
            lineWrapping: true,//滚动或换行
            scrollbarStyle: null,//隐藏滚动条样式
            tabSize: 2, //tab键缩进,默认4
            smartIndent: true, // 智能缩进
            indentUnit: 2, // 智能缩进单位为2个空格长度
            indentWithTabs: true, // 使用制表符进行智能缩进
            autofocus: true,//自动获取焦点
            // 在行槽中添加行号显示器、折叠器、语法检测器
            gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"],
            foldGutter: true, // 启用行槽中的代码折叠
            mode: "python", // 要使用的模式//https://codemirror.net/mode/
            styleActiveLine: true, // 显示选中行的样式
            matchBrackets: true,	//括号匹配
            autoCloseBrackets: true,//括号自动补全,()[]{}''""
            hintOptions: {
                completeSingle: false//代码自动补全功能不默认补充
            },
        });
        myCodeMirror.setOption("value", 'print("hello word")');//初始值
        myCodeMirror.on("keypress", function () {//代码补全功能
            myCodeMirror.showHint();
        });
        myCodeMirror.setSize('40vw', '50vh');//编辑框大小(宽,高)
    }, [])

    // 将值传给后端,后端返回运行结果
    function runFunction() {
        axios({
            method: 'post',
            url: 'http://192.168.2.139:7000/edit_api/edit',
            params: {
                code: myCodeMirror.getValue()
            },
            // timeout: 5000,
        }).then(function (res) {
            console.log('3:', res)
            if (res.data.code === 0) {
                setSubmitResult(res.data.data.output)
            }
        }).catch(function (error) {
            console.log(error);
        })
    }

    return (
        <div className={Style.mainWrapper}>
            <div className={Style.leftWrapper}>
                <div className={Style.codeTop}>
                    <Button onClick={runFunction} type='primary' >运行</Button>
                </div>
                <textarea id="editor"></textarea>
            </div>
            <div className={Style.rightWrapper}>
                <div className={Style.codeTop}>
                    <p>运行结果</p>
                </div>
                <div className={Style.codeResult}>
                    <div>{submitResult}</div>
                </div>
            </div>

        </div>
    )
}

css样式

.mainWrapper {
    height: 100vh;
    width: 100vw;
    padding: 0px 10vw;
    display: flex;
    /* justify-content: center; */
    align-items: center;
}

.leftWrapper {
    width: 40vw;
    height: 55vh;
}

.rightWrapper {
    width: 40vw;
    height: 55vh;
}

.codeTop {
    height: 5vh;
}

.codeTop p {
    font-weight: 600;
    font-size: 2vh;
}

.codeResult {
    height: 50vh;
    background-color: #263238;
    border-left: 1px solid white;
    /* 识别\n换行 */
    white-space: pre-line;
    padding: 2vh 2vw;
    overflow-y: auto;
    color: white;
}