React中CodeMirror插件的使用及封装

news2025/1/23 21:24:08

目录

一、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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3 从零开始 搭建 简单 干净 的 后台管理系统

前言&#xff1a; 记得自己大二时&#xff08;2017年&#xff09;&#xff0c;想搭建一个后台管理系统&#xff0c;当时头脑想的是用原生JS写的。我肯定干不出来&#xff0c;后来乖乖用了当时比较流行的layui&#xff0c;就算现在也真的难以做下去。 这几天&#xff0c;有了需…

微信小程序如何将表单的数据发送到数据库,云开发,并实现将数据渲染到页面中

一、表单数据发送到数据库 1. 利用bindsubmit来写一个函数 <form bindsubmit"bindSubmit"><view class"form_border"><label>收件人名称:</label><input name"userName" auto-focus placeholder" 请填写收件…

【Java编程指南】语法基础

目录 一、前言 二、关键字 三、数据类型 1.存储单元 2.存储范围 3.类型转换 四、常量 五、变量 六、标识符 七、注释 一、前言 学习目标 1&#xff1a;熟悉Java的关键字、数据类型&#xff08;包括范围&#xff09;、常量与变量的区别 学习目标 2&#xff1a;类型转…

Java项目中利用飞书自定义机器人Webhook向飞书群推送告警通知

今天来看一下如何在Java项目中利用飞书的自定义机器人Webhook向飞书群推送告警通知 一、功能场景 企业存在给特定群组自动推送消息的需求&#xff0c;比如&#xff1a;监控报警推送、销售线索推送、运营内容推送等。 你可以在群聊中添加一个自定义机器人&#xff0c;通…

vue-print 实现打印功能

目录一、安装1. Vue22. Vue3二、基本使用1. 直接打印页面HTML2. 个性化设置3. 打印URL三、API一、安装 1. Vue2 npm install vue-print-nb --saveimport Print from vue-print-nb // Global instruction Vue.use(Print);//or// Local instruction import print from vue-pri…

选 择 器

目录 1、三种基本选择器&#xff08;重要&#xff09; &#xff08;1&#xff09;基本选择器 &#xff08;2&#xff09;类选择器 class &#xff08;3&#xff09;id选择器 2、层次选择器 &#xff08;1&#xff09;后代选择器 &#xff08;2&#xff09;子选择器 &am…

【JavaScript速成之路】JavaScript内置对象--数组对象

&#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f525;系列专栏&#xff1a;【JavaScript速成之路】 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 文章目录前言数组对象1&#xff0c;数组类型检测2&#xff0c;数组元素增删3&#xff0c;…

【面试题】面试官:如果后端给你 1w 条数据,你如何做展示?

最近一位朋友参加阿b的面试&#xff0c;然后面试官问了她这个问题&#xff0c;我问她咋写的&#xff0c;她一脸淡定的说&#xff1a;“虚拟列表。”大厂面试题分享 面试题库前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面…

canvas简易使用教程

简介:<canvas> </canvas> 是 HTML5 新增的&#xff0c;一个可以使用脚本(通常为 JavaScript) 在其中绘制图像的 HTML 元素。提供了一个通过JavaScript 和 HTML的<canvas>元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑(如照片集)以及…

FilterChain(过滤器链)详解

在一个 Web 应用程序中可以注册多个 Filter 程序&#xff0c;每个 Filter 程序都可以针对某一个 URL 进行拦截。如果多个 Filter 程序都对同一个 URL 进行拦截&#xff0c;那么这些 Filter 就会组成一个Filter 链&#xff08;也称过滤器链&#xff09;。 Filter 链用 FilterCh…

vue获取文件流(视频流、音频流、图片流)数据并将其回显展示

前言 这几天深受数据回显的折磨&#xff0c;级联选择器的回显还没想出怎么弄&#xff0c;又碰到了文件流的回显&#xff0c;主要第一次接触&#xff0c;看着一堆乱码&#xff0c;连是什么问题都不懂&#xff0c;后面通过查阅一天的资料&#xff0c;总结了一下方法&#xff0c;…

Axure教程-新手入门基础(小白强烈推荐!!!)

Axure教程-新手入门基础(小白推荐) 1.Axure软件介绍 Axure RP是一款专业的快速原型设计工具。Axure&#xff08;发音&#xff1a;Ack-sure&#xff09;&#xff0c;代表美国Axure公司&#xff1b;RP则是Rapid Prototyping&#xff08;快速原型&#xff09;的缩写。 Axure RP的…

Code For Better 谷歌开发者之声——使用谷歌浏览器 Chrome 更好地调试

&#x1f482; 个人网站:【 海拥】【小霸王游戏机】&#x1f91f; 风趣幽默的前端学习课程&#xff1a;&#x1f449;28个案例趣学前端&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】&#x1f4ac; 免费且实用的计算机相关知识题库&…

layui最新版本更新已全面拥抱Vue3,layui - vue是一套Vue 3.0的桌面端组件库,提供100%的layui的体验;

layui - vue目前的版本是1.4.9&#xff0c;目前常用的大部分组件已全部覆盖&#xff0c;最惊喜的地方在动画和过度组件做的比较好&#xff0c;应该是目前Vue组件库里面做的比较好的&#xff0c;Vue的动画相比于React和Angular一直比较弱,layui - vue目前做的不错&#xff0c;目…

前端中的BFC是什么?

BFC的概念 BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域&#xff0c;只有Block-level box参与&#xff0c; 它规定了内部的Block-level Box如何布局&#xff0c;并且与这个区域外部毫不相干。 MDN给出的解释是&#xff1a;BFC是…

【docker基础操作命令】(一)启动命令和镜像命令

文章目录docker启动命令1. 启动docker2. 关闭docker3. 重启docker4. 查看docker运行状态5. 设置docker开机自启动6. 查看docker信息7. 查看docker的帮助文档docker镜像命令1. 显示当前docker下的所有镜像2. 从远程仓库查看指定名称的镜像3. 下载镜像到本地4. 查看镜像/容器/数据…

分布式ELK日志监控系统环境搭建

文章目录1.1为什么需要监控项目日志1.2ELK日志监控系统介绍1.3ELK的工作流程1.4ELK环境搭建1.4.1Elasticsearch的安装1.4.2Kibana的安装1.4.3Logstash的安装1.4.4数据源配置1.4.5日志监测测试1.1为什么需要监控项目日志 项目日志是记录项目运行过程中产生的事件和信息的重要工…

web前端开发和后端开发哪个难度大?

前言 因为涉及到的具体的应用的领域不同&#xff0c;所以说不能简单地说哪一个难&#xff0c;对于前端而言你会感觉到入门会非常的简单&#xff0c;这也是会给许多人一种错觉&#xff0c;前端很简单&#xff0c;但是只能说是在入门理解上是有利于新手的&#xff0c;前端在主要…

Python tkinter(GUI编程)模块最完整教程(上)

提示&#xff1a;下滑文章左侧可以查看目录&#xff01; 1 走进tkinter世界 1.1 认识tkinter tkinter是一个GUI开发模块&#xff0c;是Tcl/Tk语言在Python上的接口&#xff0c;可以在大部分操作系统上运行。tkinter非常的简单而且好用。tkinter模块是自带的Python模块&#…

vue3.2 基础及常用方法

Vue3.2(21年8月10日)相比于Vue3新增了语法糖,减少了代码冗余 Vue3相比于Vue2,在虚拟DOM,编译, 数据代理,打包构建封面进行了优化 Vue3使用组合式API, 适合大型项目, 去除了this vue2的 beforeCreate 和 created 被新增的setup生命周期替代 vue3 使用插件: volar 配置用户代…