react-markdown
是一款 github
上開源的適用于 react
的 markdown
組件,可以基本實(shí)現(xiàn) markdown
的功能,且可以根據(jù)自己實(shí)際應(yīng)用定制的 remark
組件。
安裝
安裝 markdown 預(yù)覽插件 react-markdown
npm install react-markdown
或者:
yarn add react-markdown
安裝 markdown 編輯器插件 for-editor
yarn add for-editor
或者:
npm install for-editor
安裝代碼高亮插件包 react-syntax-highlighter
npm install react-syntax-highlighter
或者:
yarn add react-syntax-highlighter
安裝 remark-math
npm install remark-math
或者:
yarn add remark-math
安裝 rehype-katex
npm install rehype-katex
或者:
yarn add rehype-katex
安裝 rehype-raw
npm install rehype-raw
或者:
yarn add rehype-raw
組件依賴
組件涉及的依賴及版本 package.json
:
{
"dependencies": {
"antd": "^4.16.10",
"less": "^4.1.1",
"less-loader": "4.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"for-editor": "^0.3.5", // Markdown編輯
"react-markdown": "^8.0.7", // Markdown預(yù)覽
"rehype-katex": "^6.0.2", // 數(shù)學(xué)公式katex語法
"rehype-raw": "^6.1.1", // 支持HTML語法解析
"remark-math": "^5.1.1", // 支持?jǐn)?shù)學(xué)公式
"react-scripts": "4.0.3",
"typescript": "^5.0.4",
}
}
-
for-editor
:markdown
編輯器 -
react-markdown
:markdown
內(nèi)容預(yù)覽及展示 -
rehype-raw
:解析HTML
文本富文本內(nèi)容 -
remark-math、rehype-katex
:數(shù)學(xué)公式支持及語法解析使用(數(shù)學(xué)公式的樣式展示需要katex.min.css
文件支持)
基本使用
編輯器 for-editor
屬性
名稱 | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
value | String | - | 輸入框內(nèi)容 |
placeholder | String | 開始編輯… | 占位文本 |
lineNum | Boolean | true | 是否顯示行號 |
style | Object | - | 編輯器樣式 |
height | String | 600px | 編輯器高度 |
preview | Boolean | false | 預(yù)覽模式 |
expand | Boolean | false | 全屏模式 |
subfield | Boolean | false | 雙欄模式(預(yù)覽模式激活下有效) |
language | String | zh-CN | 語言(支持 zh-CN:中文簡體, en:英文) |
toolbar | Object | 如下 | 自定義工具欄 |
/*
默認(rèn)工具欄按鈕全部開啟, 傳入自定義對象
例如: {
h1: true, // h1
code: true, // 代碼塊
preview: true, // 預(yù)覽
}
此時(shí), 僅僅顯示此三個(gè)功能鍵
注:傳入空對象則不顯示工具欄
*/
toolbar: {
h1: true, // h1
h2: true, // h2
h3: true, // h3
h4: true, // h4
img: true, // 圖片
link: true, // 鏈接
code: true, // 代碼塊
preview: true, // 預(yù)覽
expand: true, // 全屏
/* v0.0.9 */
undo: true, // 撤銷
redo: true, // 重做
save: true, // 保存
/* v0.2.3 */
subfield: true, // 單雙欄模式
}
事件
名稱 | 參數(shù) | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|---|
onChange | String: value | function(e) | - | 內(nèi)容改變時(shí)回調(diào) |
onSave | String: value | function(e) | - | 保存時(shí)回調(diào) |
addImg | File: file | function(e) | - | 添加圖片時(shí)回調(diào) |
快捷鍵
名稱 | 描述 |
---|---|
tab | 兩個(gè)空格縮進(jìn) |
ctrl+s | 保存 |
ctrl+z | 上一步 |
ctrl+y | 下一步 |
在 views/md-editor/
文件夾下面新建 MdEditor.js
文件:
import React, { useState } from "react"
import MdEditor from 'for-editor'
const DemoEditor = () => {
/** 默認(rèn)工具欄按鈕全部開啟, 傳入自定義對象
例如: {
h1: true, // h1
code: true, // 代碼塊
preview: true, // 預(yù)覽
}
此時(shí), 工具欄只顯示此三個(gè)功能鍵(注:傳入空對象則不顯示工具欄)
*/
// 工具欄菜單
const toolbar = {
h1: true, // h1
h2: true, // h2
h3: true, // h3
h4: true, // h4
img: true, // 圖片
link: true, // 鏈接
code: true, // 代碼塊
preview: true, // 預(yù)覽
expand: true, // 全屏
/* v0.0.9 */
undo: true, // 撤銷
redo: true, // 重做
save: true, // 保存
/* v0.2.3 */
subfield: true, // 單雙欄模式
};
// 保存Markdown文本內(nèi)容
const [mdContent, setMdContent] = useState('')
// 上傳圖片
function uploadImg (file) {
console.log('file', file);
};
// 輸入內(nèi)容改變
function handleEditorChange (value) {
console.log('handleChange', value);
setMdContent(value)
}
// 保存輸入內(nèi)容
function handleEditorSave (value) {
console.log('handleEditorSave', value);
}
return (
<MdEditor placeholder="請輸入Markdown文本" height={600} lineNum={false}
toolbar={toolbar} value={mdContent} onChange={handleEditorChange} onSave={handleEditorSave} addImg={uploadImg} />
)
}
export default DemoEditor
在 App.js
中引入 md-editor.js
文件:
import './assets/css/App.css';
import MdCtxEditor from './views/md-editor/MdEditor';
function App () {
return (
<div className="App">
<MdCtxEditor />
</div>
);
}
export default App;
頁面效果:
預(yù)覽 react-markdown
在 views/md-editor/
文件夾下面新建 MdPreview.js
文件:
import React, { useEffect, useState } from "react"
import ReactMarkdown from 'react-markdown'
const DemoPage = () => {
const [docmentContent, setDocmentContent] = useState('')
const content = '# This is title 1\n\n## This is title 2\n\n### This is title 3\n\nAnd this is a paragraph\n\n**A paragraph with strong importance**\n\n*A block quote with ~strikethrough~*'
useEffect(() => {
setDocmentContent(content)
}, [])
return (
<div className="markdown-body" style={{ padding: '30px', borderRadius: '10px' }}>
<ReactMarkdown children={docmentContent} />
</div>
)
}
export default DemoPage
在 App.js
中引入 MdPreview.js
文件:
import './assets/css/App.css';
import MdCtxPreview from './views/md-editor/MdPreview';
function App () {
return (
<div className="App">
<MdCtxPreview />
</div>
);
}
export default App;
頁面效果:
代碼塊高亮
修改 MdPreview.js
文件:
import React, { useEffect, useState } from "react"
import ReactMarkdown from 'react-markdown'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
// 設(shè)置高亮樣式
import { xonokai } from 'react-syntax-highlighter/dist/esm/styles/prism'
const Code = {
code ({ node, inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<SyntaxHighlighter
children={String(children).replace(/\n$/, '')}
style={xonokai}
language={match[1]}
PreTag="div"
{...props}
/>
) : (
<code className={className} {...props}>
{children}
</code>
)
}
}
const DemoPage = () => {
const [docmentContent, setDocmentContent] = useState('')
const content = `This is some JavaScript code:
~~~js
console.log('Hello world!')
~~~
`
useEffect(() => {
setDocmentContent(content)
}, [])
return (
<div className="markdown-body" style={{ padding: '30px', borderRadius: '10px' }}>
<ReactMarkdown
children={docmentContent}
components={Code}
/>
</div>
)
}
export default DemoPage
頁面效果:
支持 HTML
修改 MdPreview.js
文件:
import React, { useEffect, useState } from "react"
import ReactMarkdown from 'react-markdown'
import rehypeRaw from 'rehype-raw';
const DemoPage = () => {
const [docmentContent, setDocmentContent] = useState('')
const content = `<div class="note">Some *emphasis* and <strong>strong</strong>!</div>`
useEffect(() => {
setDocmentContent(content)
}, [])
return (
<div className="markdown-body" style={{ padding: '30px', borderRadius: '10px' }}>
<ReactMarkdown children={docmentContent}
rehypePlugins={[rehypeRaw]} />
</div>
)
}
export default DemoPage
頁面效果:
rehype-katex 和 remark-math 展示數(shù)學(xué)公式
使用 rehype-katex
和 remark-math
可以輕松的翻譯輸入的數(shù)學(xué)公式。
注意:需要使用 katex.css
來展示相應(yīng)的效果,否則會(huì)出現(xiàn)公式亂掉的 BUG
。
在 index.html
中引入公式解析樣式文件:
<!-- 解析Markdown數(shù)學(xué)公式樣式 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.13/dist/katex.min.css" integrity="sha384-RZU/ijkSsFbcmivfdRBQDtwuwVqK7GMOw6IMvKyeWL2K5UAlyp6WonmB8m7Jd0Hn" crossorigin="anonymous">
修改 MdPreview.js
文件:
import React, { useEffect, useState } from "react"
import ReactMarkdown from 'react-markdown'
import remarkMath from 'remark-math'
import rehypeKatex from 'rehype-katex'
const DemoPage = () => {
const [docmentContent, setDocmentContent] = useState('')
const ctx = `$$
I = \int_0^{2\pi} \sin(x)\,dx
$$`
useEffect(() => {
setDocmentContent(ctx)
}, [])
return (
<div className="markdown-body" style={{ padding: '30px', borderRadius: '10px' }}>
<ReactMarkdown
children={docmentContent}
remarkPlugins={[remarkMath]}
rehypePlugins={[rehypeKatex]}
/>
</div>
)
}
export default DemoPage
頁面效果:文章來源:http://www.zghlxwxcb.cn/news/detail-642403.html
相關(guān)鏈接
react-markdown github 源碼
for-editor github
markdown-navbar github文章來源地址http://www.zghlxwxcb.cn/news/detail-642403.html
到了這里,關(guān)于React markdown 編輯器的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!