React+TypeScript項(xiàng)目中使用CodeMirror的步驟
前言
之前做需求用到過codeMirror這個工具,覺得還不錯,功能很強(qiáng)大,所以記錄一下改工具的基礎(chǔ)用法,分享給大家。CodeMirror被廣泛應(yīng)用于許多Web應(yīng)用程序和開發(fā)工具,例如代碼編輯器、集成開發(fā)環(huán)境(IDE)、在線教育平臺等。它提供了一個可嵌入的、靈活的解決方案,讓開發(fā)者可以輕松地在網(wǎng)頁中實(shí)現(xiàn)功能強(qiáng)大的代碼編輯器。
使用codeMirror
步驟1:安裝依賴
首先,你需要在React項(xiàng)目中安裝CodeMirror及其相關(guān)依賴??梢允褂靡韵旅钸M(jìn)行安裝:
npm install codemirror react-codemirror2 @types/codemirror
步驟2:導(dǎo)入所需模塊、創(chuàng)建CodeMirror組件
import React, { useRef, useEffect } from 'react';
import CodeMirror, { EditorFromTextArea } from 'codemirror';
import 'codemirror/lib/codemirror.css';
// 導(dǎo)入需要的語言模式和樣式主題
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 () => {
// 清理和銷毀編輯器實(shí)例
editorRef.current?.toTextArea();
};
}, []);
const initCodeMirror = ()=>{
const editorConfig = {
tabSize: 2, // 制表符的寬度。默認(rèn)為 4。
fontSize: '16px', // 字體大小
autoCloseBrackets: true, // 在鍵入時自動關(guān)閉括號和引號
showCursorWhenSelecting: true, // 當(dāng)選擇處于活動狀態(tài)時是否應(yīng)繪制光標(biāo)。默認(rèn)為 false。這里設(shè)置成自動補(bǔ)全
lineWrapping: true, // ,CodeMirror 是否應(yīng)該滾動或換行。默認(rèn)為false(滾動)。這里設(shè)置成換行
lineNumbers: true, // 是否在編輯器左側(cè)顯示行號
fullScreen: true, //當(dāng)設(shè)置為 時true,將使編輯器全屏顯示(如占據(jù)整個瀏覽器窗口)。
mode:language, // 使用模式
theme: 'material' // 編輯器樣式的主題 必須確保.cm-s-[name] 加載定義相應(yīng)樣式的 CSS 文件。默認(rèn)值為"default",顏色包含在 中codemirror.css??梢砸淮问褂枚鄠€主題類,例如將和類"foo bar"都分配給編輯器。cm-s-foocm-s-bar
};
editorRef.current = CodeMirror.fromTextArea(textareaRef.current!, editorConfig);
// 監(jiān)聽編輯器內(nèi)容變化事件
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();
}
};
/** 編輯內(nèi)容變化 */
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組件
在你的應(yīng)用程序中,使用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代碼提示
因?yàn)樯厦嫱暾幕A(chǔ)代碼已有,下面的代碼我只寫一些需要額外加進(jìn)去的部分。關(guān)鍵字可以自己添加,這里只是給個例子看看。當(dāng)然也可以添加其他語言的提示,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;
// 假設(shè)你的關(guān)鍵字列表存儲在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 () => {
// 清理和銷毀編輯器實(shí)例
editorRef.current?.toTextArea();
};
}, []);2、在codemirrorValueChange函數(shù)里加入下面代碼
/** 編輯內(nèi)容變化 */
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編輯器實(shí)例,它是你創(chuàng)建的編輯器對象的引用。- 第二個參數(shù)是可選的,用于指定觸發(fā)自動完成的原因??梢詡魅胍粋€字符串作為原因,例如
"explicit"表示顯式觸發(fā),或者傳入undefined表示由編輯器自動觸發(fā)。 - 第三個參數(shù)是可選的配置對象,用于自動完成的選項(xiàng)。在這里,
{ completeSingle: false }設(shè)置了completeSingle選項(xiàng)為false,表示自動完成功能不會在只有一個建議項(xiàng)時立即完成,而是等待更多的輸入或手動觸發(fā)。
更多配置請自行去官網(wǎng)文檔查看https://codemirror.net/5/doc/manual.html#config
到此這篇關(guān)于React+TypeScript項(xiàng)目中使用CodeMirror的方法的文章就介紹到這了,更多相關(guān)React+TypeScript項(xiàng)目使用CodeMirror內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React項(xiàng)目中使用zustand狀態(tài)管理的實(shí)現(xiàn)
zustand是一個用于狀態(tài)管理的小巧而強(qiáng)大的庫,本文主要介紹了React項(xiàng)目中使用zustand狀態(tài)管理的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-10-10
react進(jìn)階教程之異常處理機(jī)制error?Boundaries
在react中一旦出錯,如果每個組件去處理出錯情況則比較麻煩,下面這篇文章主要給大家介紹了關(guān)于react進(jìn)階教程之異常處理機(jī)制error?Boundaries的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
react-native-video實(shí)現(xiàn)視頻全屏播放的方法
這篇文章主要介紹了react-native-video實(shí)現(xiàn)視頻全屏播放的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
React中useState的使用方法及注意事項(xiàng)
useState通過在函數(shù)組件里調(diào)用它來給組件添加一些內(nèi)部state,下面這篇文章主要給大家介紹了關(guān)于React中useState的使用方法及注意事項(xiàng)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
詳解React如何實(shí)現(xiàn)代碼分割Code Splitting
這篇文章主要為大家介紹了React如何實(shí)現(xiàn)代碼分割Code Splitting示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
關(guān)于hooks中useEffect()的使用總結(jié)
這篇文章主要介紹了關(guān)于hooks中useEffect()的使用總結(jié),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
react中axios結(jié)合后端實(shí)現(xiàn)GET和POST請求方式
這篇文章主要介紹了react中axios結(jié)合后端實(shí)現(xiàn)GET和POST請求方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02

