当前位置: 首页 > news >正文

页面编辑器CodeMirror初始化不显示行号或文本内容

 延迟刷新

本来想延迟100毫秒的,但是会出现样式向左偏移的情况,于是试了试500毫秒,发现就没有问题了,可能是样式什么是需要一个加载过程吧。

  useEffect(() => {
    editorRef.current?.setValue(value || '');
    setTimeout(() => {
      editorRef.current?.refresh();
    }, 500);
  }, [value]);

另外记录一下写的编辑器组件

npm install codemirror  --save

import CodeMirror, { EditorFromTextArea } from 'codemirror';
import 'codemirror/lib/codemirror.css';
import React, { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';

// 导入需要的语言模式和样式主题
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/addon/hint/javascript-hint.js'; // 自动提示
import 'codemirror/mode/htmlmixed/htmlmixed';
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/xml/xml';
import 'codemirror/theme/material.css'; // 加载的样式主题 https://codemirror.net/5/theme/

// 折叠代码块
import 'codemirror/addon/fold/brace-fold.js';
import 'codemirror/addon/fold/comment-fold.js';
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/foldgutter.js';

import 'codemirror/addon/selection/active-line.js'; // 当前行高亮

import 'codemirror/addon/hint/anyword-hint.js'; // end
import 'codemirror/addon/hint/show-hint.css'; // start-ctrl+空格代码提示补全
import 'codemirror/addon/hint/show-hint.js';

// 定义组件属性类型
interface CodeMirrorEditorProps {
  ref: any;
  readOnly: boolean;
  value: string;
  language: string;
  theme?: 'default' | 'material';
  height?: number;
  width?: number;
  onChange: (value: string) => void;
  onShiftEnter?: () => void;
  onBlur?: (value: string) => void;
  onChangeLine?: () => void;
}

const CodeMirrorEditor: React.FC<CodeMirrorEditorProps> = forwardRef((props, ref) => {
  const { language, readOnly, value, theme, width, height } = props;
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const editorRef = useRef<EditorFromTextArea>();

  useImperativeHandle(ref, () => ({
    refresh: () => {
      editorRef.current?.refresh();
    },
  }));

  /** 失焦 */
  const blur = (instance: any) => {
    if (props.onBlur) {
      props.onBlur(instance.doc.getValue());
    }
  };

  /** 键盘按键按下 */
  const keydown = (_: any, change: any) => {
    if (change.shiftKey === true && change.keyCode === 13) {
      if (props.onShiftEnter) {
        props.onShiftEnter();
      }
      change.preventDefault();
    }
  };

  /** 编辑内容变化 */
  const codemirrorValueChange = (doc: any, change: any) => {
    doc.eachLine((line: any) => {
      if (line.text.startsWith('//') || line.text.startsWith('#')) {
        doc.addLineClass(line, 'wrap', 'notes');
      } else if (line.wrapClass === 'notes') {
        doc.removeLineClass(line, 'wrap', 'notes');
      }
    });

    if (change.origin !== 'setValue') {
      if (props.onChange) {
        props.onChange(doc.getValue());
      }
    }
  };

  const initCodeMirror = () => {
    const editorConfig = {
      readOnly: readOnly,
      tabSize: 4, // 制表符的宽度。默认为 4。
      fontSize: '16px', // 字体大小
      styleActiveLine: !readOnly, // 选中行高亮
      autoCloseBrackets: true, // 在键入时自动关闭括号和引号
      showCursorWhenSelecting: true, // 当选择处于活动状态时是否应绘制光标。默认为 false。这里设置成自动补全
      lineWrapping: true, // ,CodeMirror 是否应该滚动或换行。默认为false(滚动)。这里设置成换行
      lineNumbers: true, // 是否在编辑器左侧显示行号
      firstLineNumber: 1,
      fullScreen: true, //当设置为 时true,将使编辑器全屏显示(如占据整个浏览器窗口)。
      mode: language, // 使用模式
      // theme: 'default' // 编辑器样式的主题 必须确保.cm-s-[name] 加载定义相应样式的 CSS 文件。默认值为"default",颜色包含在 中codemirror.css。可以一次使用多个主题类,例如将和类"foo bar"都分配给编辑器。cm-s-foocm-s-bar
      theme: theme || 'default', // 编辑器样式的主题 必须确保.cm-s-[name] 加载定义相应样式的 CSS 文件。默认值为"default",颜色包含在 中codemirror.css。可以一次使用多个主题类,例如将和类"foo bar"都分配给编辑器。cm-s-foocm-s-bar
      foldGutter: true,
      gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
      extraKeys: { Ctrl: 'autocomplete' },
    };

    editorRef.current = CodeMirror.fromTextArea(textareaRef.current!, editorConfig);

    // 监听编辑器内容变化事件
    editorRef.current.on('change', codemirrorValueChange);
    editorRef.current.on('keydown', keydown);
    editorRef.current.on('blur', blur);

    // const { value, width, height } = props;
    editorRef.current.setValue(value || '');
    if (width || height) {
      editorRef.current.setSize(width, height);
    }
  };

  useEffect(() => {
    if (textareaRef.current) {
      initCodeMirror();
    }

    return () => {
      // 清理和销毁编辑器实例
      editorRef.current?.toTextArea();
    };
  }, [readOnly, textareaRef, theme, width, height, language]);

  useEffect(() => {
    editorRef.current?.setValue(value || '');
    setTimeout(() => {
      editorRef.current?.refresh();
    }, 500);
  }, [value]);

  return <textarea ref={textareaRef} />;
});

export default CodeMirrorEditor;

使用

import { CodeMirrorEditor } from '@/components';
<CodeMirrorEditor
     height={550}
     theme={'default'}
     readOnly={false}
     value={content || ''}
     language="javascript"
     onChange={(value) => {
       console.log('值',value)
   }}
 />

相关文章:

  • docker内安装达梦8数据库
  • PhotoShop学习09
  • 设计模式:单例模式
  • AI大模型与知识生态:重构认知的新时代引擎
  • 将mongdb中文档转储到mysql设计思路
  • 众趣科技丨沉浸式 VR 体验,助力酒店民宿数字化营销宣传
  • Maya云渲染工作流,提升渲染速度
  • C++蓝桥杯填空题(攻克版)
  • NLP高频面试题(三十八)——什么是LLM的灾难性遗忘?如何避免灾难性遗忘?
  • C++手写std::function
  • Three.js关键帧动画不连续正放、倒放出现的部分问题
  • 【PVR Review】《A Review of Palmar Vein Recognition》
  • atypica.AI:用「语言模型」为「主观世界」建模
  • Redis的哨兵
  • 深度学习基础--CNN经典网络之分组卷积与ResNext网络实验探究(pytorch复现)
  • EasyX 图形库学习笔记
  • c#程序结构
  • 单北斗终端:铸就国产科技脊梁
  • 告别 ifconfig:为什么现代 Linux 系统推荐使用 ip 命令
  • 【蓝桥杯Web】2022年十三届省赛大学组真题 冬奥大抽奖 介绍 蓝桥云课庆冬奥需要举行一次抽奖活动,我们一起做一个页面提供给云课冬奥抽奖活动使用。
  • 兰州 网站建设/杭州seo建站
  • 网站怎样做谷歌推广/北京seo网站设计
  • 搭建vpn访问国外网站/哪些平台可以免费发布产品
  • 建设信用卡中心网站首页/广州网站建设系统
  • 网站建设新闻 常识/北京做网站的公司有哪些
  • 恒星科技网站建设/深圳专业建站公司