React+TypeScript項目中使用CodeMirror的步驟
前言
之前做需求用到過codeMirror這個工具,覺得還不錯,功能很強大,所以記錄一下改工具的基礎用法,分享給大家。CodeMirror被廣泛應用于許多Web應用程序和開發(fā)工具,例如代碼編輯器、集成開發(fā)環(huán)境(IDE)、在線教育平臺等。它提供了一個可嵌入的、靈活的解決方案,讓開發(fā)者可以輕松地在網(wǎng)頁中實現(xiàn)功能強大的代碼編輯器。
使用codeMirror
步驟1:安裝依賴
首先,你需要在React項目中安裝CodeMirror及其相關依賴。可以使用以下命令進行安裝:
npm install codemirror react-codemirror2 @types/codemirror
步驟2:導入所需模塊、創(chuàng)建CodeMirror組件
import React, { useRef, useEffect } from 'react'; import CodeMirror, { EditorFromTextArea } from 'codemirror'; import 'codemirror/lib/codemirror.css'; // 導入需要的語言模式和樣式主題 import 'codemirror/mode/javascript/javascript'; import 'codemirror/mode/xml/xml'; import 'codemirror/mode/css/css'; import 'codemirror/mode/htmlmixed/htmlmixed'; import 'codemirror/theme/material.css'; // 加載的樣式主題 https://codemirror.net/5/theme/ // 定義組件屬性類型 interface CodeMirrorEditorProps { value: string; language: string; theme?: string; height?:Number; width?:Number; onChange: (value: string) => void; onShiftEnter?: () => void; onBlur?: (value: string) => void; onChangeLine?: () => void; } const CodeMirrorEditor: React.FC<CodeMirrorEditorProps> = (props) => { const { language } = props; const textareaRef = useRef<HTMLTextAreaElement>(null); const editorRef = useRef<EditorFromTextArea>(); useEffect(() => { const textarea = textareaRef.current; if (!textarea) return; initCodeMirror(); return () => { // 清理和銷毀編輯器實例 editorRef.current?.toTextArea(); }; }, []); const initCodeMirror = ()=>{ const editorConfig = { tabSize: 2, // 制表符的寬度。默認為 4。 fontSize: '16px', // 字體大小 autoCloseBrackets: true, // 在鍵入時自動關閉括號和引號 showCursorWhenSelecting: true, // 當選擇處于活動狀態(tài)時是否應繪制光標。默認為 false。這里設置成自動補全 lineWrapping: true, // ,CodeMirror 是否應該滾動或換行。默認為false(滾動)。這里設置成換行 lineNumbers: true, // 是否在編輯器左側顯示行號 fullScreen: true, //當設置為 時true,將使編輯器全屏顯示(如占據(jù)整個瀏覽器窗口)。 mode:language, // 使用模式 theme: 'material' // 編輯器樣式的主題 必須確保.cm-s-[name] 加載定義相應樣式的 CSS 文件。默認值為"default",顏色包含在 中codemirror.css??梢砸淮问褂枚鄠€主題類,例如將和類"foo bar"都分配給編輯器。cm-s-foocm-s-bar }; editorRef.current = CodeMirror.fromTextArea(textareaRef.current!, editorConfig); // 監(jiān)聽編輯器內容變化事件 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); } } /** 失焦 */ 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()); } } }; return ( <textarea ref={textareaRef} /> ); }; export default CodeMirrorEditor;
步驟3:使用CodeMirror組件
在你的應用程序中,使用MyComponent
組件來渲染CodeMirror。
import React, { useState } from 'react'; import CodeMirrorEditor from 'CodeMirror'; const CodeEditor: React.FC = () => { const [code, setCode] = useState<string>(''); const handleCodeChange = (value: string) => { setCode(value); }; return ( <div> <CodeMirrorEditor value=[code] language="javascript" onChange={handleCodeChange} /> <pre>[code]</pre> </div> ); }; export default CodeEditor;
步驟4:添加樣式
在添加了CodeMirror所需的樣式。
.CodeMirror { height: 300px; }
注冊Js代碼提示
因為上面完整的基礎代碼已有,下面的代碼我只寫一些需要額外加進去的部分。關鍵字可以自己添加,這里只是給個例子看看。當然也可以添加其他語言的提示,registerHelper函數(shù)的第二個參數(shù)就是所配置的語言,和editorConfig 里面的mode保持一致。
// 注冊JavaScript代碼提示 const registerHelp = () =>{ CodeMirror.registerHelper('hint', 'javascript', (editor, options) => { const cursor = editor.getCursor(); const token = editor.getTokenAt(cursor); const word = token.string; // 假設你的關鍵字列表存儲在keywords數(shù)組中 const keywords = ['if', 'else', 'for', 'while', 'function', 'class']; const list = keywords.filter((keyword) => keyword.startsWith(word)); return { list, from: CodeMirror.Pos(cursor.line, token.start), to: CodeMirror.Pos(cursor.line, token.end), }; }); }
1、需要將上面的代碼放在初始化codeMirror之上
useEffect(() => { const textarea = textareaRef.current; if (!textarea) return; registerHelp(); // 注冊代碼提示 initCodeMirror(); return () => { // 清理和銷毀編輯器實例 editorRef.current?.toTextArea(); }; }, []);
2、在codemirrorValueChange函數(shù)里加入下面代碼
/** 編輯內容變化 */ 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 === '+input') { CodeMirror.commands.autocomplete(editor.current, undefined, { completeSingle: false, }); } if (change.origin !== 'setValue') { if (props.onChange) { props.onChange(doc.getValue()); } } };
使用了 CodeMirror
庫的autocomplete
命令來觸發(fā)自動完成功能。
CodeMirror.commands.autocomplete
接受三個參數(shù):
editor.current
:一個CodeMirror編輯器實例,它是你創(chuàng)建的編輯器對象的引用。- 第二個參數(shù)是可選的,用于指定觸發(fā)自動完成的原因??梢詡魅胍粋€字符串作為原因,例如
"explicit"
表示顯式觸發(fā),或者傳入undefined
表示由編輯器自動觸發(fā)。 - 第三個參數(shù)是可選的配置對象,用于自動完成的選項。在這里,
{ completeSingle: false }
設置了completeSingle
選項為false
,表示自動完成功能不會在只有一個建議項時立即完成,而是等待更多的輸入或手動觸發(fā)。
更多配置請自行去官網(wǎng)文檔查看https://codemirror.net/5/doc/manual.html#config
到此這篇關于React+TypeScript項目中使用CodeMirror的方法的文章就介紹到這了,更多相關React+TypeScript項目使用CodeMirror內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
React項目中使用zustand狀態(tài)管理的實現(xiàn)
zustand是一個用于狀態(tài)管理的小巧而強大的庫,本文主要介紹了React項目中使用zustand狀態(tài)管理的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-10-10react進階教程之異常處理機制error?Boundaries
在react中一旦出錯,如果每個組件去處理出錯情況則比較麻煩,下面這篇文章主要給大家介紹了關于react進階教程之異常處理機制error?Boundaries的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-08-08react-native-video實現(xiàn)視頻全屏播放的方法
這篇文章主要介紹了react-native-video實現(xiàn)視頻全屏播放的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03詳解React如何實現(xiàn)代碼分割Code Splitting
這篇文章主要為大家介紹了React如何實現(xiàn)代碼分割Code Splitting示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08react中axios結合后端實現(xiàn)GET和POST請求方式
這篇文章主要介紹了react中axios結合后端實現(xiàn)GET和POST請求方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02