目录

一、CodeMirror是什么

二、React中CodeMirror的基本使用介绍

(一)引入CodeMirror

1. 安装CodeMirror插件

2.引入 CodeMirror 插件

(二)引入文件配置

(三)关键属性解读

1.value

2.mode

3.theme

4.readOnly

5.options

(四)CodeMirror内容更新

三、CodeMirror的封装详解


一、CodeMirror是什么

        在前端交互丰富的业务场景中,难免会遇到需要编译器的情况。CodeMirror是一个代码编辑器组件,可以嵌入到Web页面中。用来满足代码书写的交互场景。

        例如:

React中CodeMirror插件的使用及封装

二、React中CodeMirror的基本使用介绍

详细的中文文档参考博客:CodeMirror用户手册_LingMax2013的博客-CSDN博客_codemirror中文文档

英文文档参考官网:

 CodeMirror 5 User Manual

(一)引入CodeMirror

1. 安装CodeMirror插件

npm install codemirror react-codemirror2 --save      //安装CodeMirror

2.引入 CodeMirror 插件

import CodeMirror from 'react-codemirror';

(二)引入文件配置

require('codemirror/lib/codemirror.css');//关键信息引入
require('codemirror/theme/seti.css');//引入主题颜色
require('codemirror/addon/display/fullscreen.css');
require('../../styles/codemirror.less');//引入样式
require('codemirror/addon/display/panel');
require('codemirror/mode/xml/xml');//引入编辑语言  xml
require('codemirror/mode/javascript/javascript');//引入编辑语言  JavaScript
require('codemirror/mode/yaml/yaml');//引入编辑语言 yaml
require('codemirror/addon/display/fullscreen');
require('codemirror/addon/edit/matchbrackets');
require ('codemirror/addon/selection/active-line');//代码高亮
require ('codemirror/addon/fold/foldgutter.css'); // 代码折叠
require ('codemirror/addon/fold/foldcode.js');// 代码折叠
require ('codemirror/addon/fold/foldgutter.js');  // 代码折叠
require ('codemirror/addon/fold/brace-fold.js');  // 代码折叠
require ('codemirror/addon/fold/comment-fold.js');// 代码折叠

(三)关键属性解读

1.value

        作为插件的初始值,写入命令行内。

2.mode

        作为鉴定输入文本框的文本类型,如JavaScript和yaml文件。

3.theme

        引入的主题。

4.readOnly

        设置为是否可读。

5.options

        各类配置的集合,作为属性传入CodeMirror插件之中

React中CodeMirror插件的使用及封装

(四)CodeMirror内容更新

        调用官方文档中的setValue方法,具体可查看官方文档。

        先获取dom节点,通过ref或者设置id拿到真实的dom节点,在通过dom.setValue设置新的内容。


//使用引入的codemirror组件
  <CodeMirror
       options={options}
       value={text ? text :"-" }
       ref={(c) => this.myCodeMirror = c}//添加ref属性获取dome节点
  />
//通过点击事件获取新的内容
    showDrawer = (val) => {
        if (this.myCodeMirror != (undefined || null)){
            const editor = this.myCodeMirror.getCodeMirror();
            editor.setValue(val)
        }
        this.setState({
            showDrawerswitch: !this.state.showDrawerswitch
        })
    }

三、CodeMirror的封装详解

import { Upload } from 'antd';
import React, { PureComponent } from 'react';
import CodeMirror from 'react-codemirror';
import apiconfig from '../../../config/api.config';
import cookie from '../../utils/cookie';
import globalUtil from '../../utils/global';
import styles from './index.less';
require('codemirror/lib/codemirror.css');
require('codemirror/theme/seti.css');
require('codemirror/addon/display/fullscreen.css');
require('../../styles/codemirror.less');
require('codemirror/addon/display/panel');
require('codemirror/mode/xml/xml');
require('codemirror/mode/javascript/javascript');
require('codemirror/mode/yaml/yaml');
require('codemirror/addon/display/fullscreen');
require('codemirror/addon/edit/matchbrackets');
// eslint-disable-next-line react/no-redundant-should-component-update
class CodeMirrorForm extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      fullScreen: false
    };
    this.CodeMirrorRef = '';
  }
  componentWillReceiveProps(nextProps) {
    const { name, data, setFieldsValue } = this.props;
    const { CodeMirrorRef } = this;
    if (data !== nextProps.data && CodeMirrorRef) {
      setFieldsValue({
        [name]: nextProps.data
      });
      if (CodeMirrorRef) {
        const editor = CodeMirrorRef.getCodeMirror();
        editor.setValue(nextProps.data);
      }
    }
  }
  saveRef = ref => {
    this.CodeMirrorRef = ref;
    const { saveRef = false } = this.props;
    if (saveRef) {
      saveRef(ref);
    }
  };
  handleChangeUpload = info => {
    const { beforeUpload } = this.props;
    if (beforeUpload) {
      if (beforeUpload(info.file, false)) {
        this.handleFile(info);
      }
      return null;
    }
    return this.handleFile(info);
  };
  handleFile = info => {
    let fileList = [...info.fileList];
    if (fileList.length > 0) {
      fileList = fileList.slice(-1);
      this.readFileContents(fileList, 'file_content');
    }
  };
  readFileContents = fileList => {
    let fileString = '';
    const { CodeMirrorRef } = this;
    const { name, setFieldsValue } = this.props;
    for (let i = 0; i < fileList.length; i++) {
      const reader = new FileReader(); // 新建一个FileReader
      reader.readAsText(fileList[i].originFileObj, 'UTF-8'); // 读取文件
      // eslint-disable-next-line no-loop-func
      reader.onload = evt => {
        // 读取完文件之后会回来这里
        fileString += evt.target.result; // 读取文件内容
        setFieldsValue({
          [name]: fileString
        });
        if (CodeMirrorRef) {
          const editor = CodeMirrorRef.getCodeMirror();
          editor.setValue(fileString);
        }
      };
    }
  };
  checkValue = (_, value, callback) => {
    const { message } = this.props;
    if (value === '' || !value || (value && value.trim() === '')) {
      callback(message);
      return;
    }
    callback();
  };
  render() {
    const {
      Form,
      getFieldDecorator,
      formItemLayout,
      data,
      label,
      name,
      message,
      width: proWidth,
      mode,
      action,
      beforeUpload,
      isHeader = true,
      isUpload = true,
      isAmplifications = true,
      disabled = false,
      titles,
      bg = '#333',
      help
    } = this.props;
    const { fullScreen } = this.state;
    let defaultFullScreenStyle = {
      display: 'flex',
      justifyContent: 'space-between',
      cursor: 'pointer',
      top: '0',
      textAlign: 'left',
      background: bg,
      lineHeight: '1px',
      padding: '9px 0 6px 0'
    };
    if (fullScreen) {
      defaultFullScreenStyle = Object.assign(defaultFullScreenStyle, {
        position: 'fixed',
        right: '5px',
        width: '100%',
        zIndex: 99
      });
    } else {
      defaultFullScreenStyle = Object.assign(defaultFullScreenStyle, {
        position: 'absolute',
        width: proWidth || '100%',
        zIndex: 4
      });
    }
    const options = {
      mode: { name: mode || 'javascript', json: true },
      lineNumbers: true,
      theme: 'seti',
      fullScreen,
      lineWrapping: true,
      smartIndent: true,
      matchBrackets: true,
      scrollbarStyle: null,
      showCursorWhenSelecting: true,
      readOnly: disabled
    };
    const token = cookie.get('token');
    const amplifications = (
      <span
        style={{ margin: '0 20px' }}
        onClick={() => {
          this.setState({ fullScreen: !this.state.fullScreen });
        }}
      >
        {globalUtil.fetchSvg('amplifications')}
      </span>
    );
    return (
      <Form.Item
        {...formItemLayout}
        label={label}
        help={help && <span style={{ color: 'red' }}>{help}</span>}
        className={
          fullScreen
            ? `${styles.fullScreens} ${styles.childrenWidth}`
            : styles.childrenWidth
        }
      >
        {getFieldDecorator(name, {
          initialValue: data || '',
          rules: [{ required: true, validator: this.checkValue }]
        })(<CodeMirror options={options} ref={this.saveRef} />)}
        {amplifications}
        {isHeader && (
          <div style={defaultFullScreenStyle}>
            <div
              style={{ lineHeight: '20px', paddingLeft: '30px', color: '#fff' }}
            >
              {titles || ''}
            </div>
            <div>
              {isUpload && (
                <Upload
                  action={
                    action ||
                    `${apiconfig.baseUrl}/console/enterprise/team/certificate`
                  }
                  showUploadList={false}
                  withCredentials
                  headers={{ Authorization: `GRJWT ${token}` }}
                  beforeUpload={beforeUpload || false}
                  onChange={this.handleChangeUpload}
                >
                  {globalUtil.fetchSvg('uploads')}
                </Upload>
              )}
              {isAmplifications && amplifications}
            </div>
          </div>
        )}
      </Form.Item>
    );
  }
}
export default CodeMirrorForm;

发表回复