目录
一、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的基本使用介绍
详细的中文文档参考博客: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插件之中
(四)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;