Vue3中使用CodeMirror出现setValue后点击报错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3中使用CodeMirror出现setValue后点击报错相关的知识,希望对你有一定的参考价值。

参考技术A 环境:

Vue3中使用CodeMirror出现setValue后点击报错、按键报错、光标显示错乱。

vue对绑定到vue组件的对象有代理,以便监控修改而刷新界面等。

codeMirror调用成员函数必须是从原始对象调用。

新建CodeMirror时使用markRaw标记后绑定要Vue组件。cm对象不需要被vue追踪。

[1] https://www.jianshu.com/p/c0b103082889

React中CodeMirror插件的使用及封装

目录

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

以上是关于Vue3中使用CodeMirror出现setValue后点击报错的主要内容,如果未能解决你的问题,请参考以下文章

vue-codemirror代码格式化后,怎样压缩代码

将 SELECT MAX(`Id`) FROM Table 传递给 setval()

React中CodeMirror插件的使用及封装

CodeMirror使用

在vue里使用codemirror的两种用法

CodeMirror---实现关键词高亮