?延遲刷新
本來想延遲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-bartheme: theme || 'default', // 編輯器樣式的主題 必須確保.cm-s-[name] 加載定義相應樣式的 CSS 文件。默認值為"default",顏色包含在 中codemirror.css。可以一次使用多個主題類,例如將和類"foo bar"都分配給編輯器。cm-s-foocm-s-barfoldGutter: 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';
<CodeMirrorEditorheight={550}theme={'default'}readOnly={false}value={content || ''}language="javascript"onChange={(value) => {console.log('值',value)}}/>