React markdown 编辑器

react-markdown 是一款 github 上开源的适用于 reactmarkdown 组件,可以基本实现 markdown 的功能,且可以根据自己实际应用定制的 remark 组件。

安装

安装 markdown 预览插件 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预览
    "rehype-katex": "^6.0.2", // 数学公式katex语法
    "rehype-raw": "^6.1.1", // 支持HTML语法解析
    "remark-math": "^5.1.1", // 支持数学公式 
    "react-scripts": "4.0.3",
    "typescript": "^5.0.4",
  }
}
  • for-editormarkdown 编辑器
  • react-markdownmarkdown 内容预览及展示
  • rehype-raw:解析 HTML 文本富文本内容
  • remark-math、rehype-katex:数学公式支持及语法解析使用(数学公式的样式展示需要 katex.min.css 文件支持)

基本使用

编辑器 for-editor

属性

名称 类型 默认值 描述
value String - 输入框内容
placeholder String 开始编辑… 占位文本
lineNum Boolean true 是否显示行号
style Object - 编辑器样式
height String 600px 编辑器高度
preview Boolean false 预览模式
expand Boolean false 全屏模式
subfield Boolean false 双栏模式(预览模式激活下有效)
language String zh-CN 语言(支持 zh-CN:中文简体, en:英文)
toolbar Object 如下 自定义工具栏
/*
  默认工具栏按钮全部开启, 传入自定义对象
  例如: {
    h1: true, // h1
    code: true, // 代码块
    preview: true, // 预览
  }
  此时, 仅仅显示此三个功能键
  注:传入空对象则不显示工具栏
 */

toolbar: {
    
    
  h1: true, // h1
  h2: true, // h2
  h3: true, // h3
  h4: true, // h4
  img: true, // 图片
  link: true, // 链接
  code: true, // 代码块
  preview: true, // 预览
  expand: true, // 全屏
  /* v0.0.9 */
  undo: true, // 撤销
  redo: true, // 重做
  save: true, // 保存
  /* v0.2.3 */
  subfield: true, // 单双栏模式
}

事件

名称 参数 类型 默认值 描述
onChange String: value function(e) - 内容改变时回调
onSave String: value function(e) - 保存时回调
addImg File: file function(e) - 添加图片时回调

快捷键

名称 描述
tab 两个空格缩进
ctrl+s 保存
ctrl+z 上一步
ctrl+y 下一步

views/md-editor/ 文件夹下面新建 MdEditor.js 文件:

import React, {
    
     useState } from "react"
import MdEditor from 'for-editor'

const DemoEditor = () => {
    
    
  /** 默认工具栏按钮全部开启, 传入自定义对象
  例如: {
    h1: true, // h1
    code: true, // 代码块
    preview: true, // 预览
  }
  此时, 工具栏只显示此三个功能键(注:传入空对象则不显示工具栏)
  */
  // 工具栏菜单
  const toolbar = {
    
    
    h1: true, // h1
    h2: true, // h2
    h3: true, // h3
    h4: true, // h4
    img: true, // 图片
    link: true, // 链接
    code: true, // 代码块
    preview: true, // 预览
    expand: true, // 全屏
    /* v0.0.9 */
    undo: true, // 撤销
    redo: true, // 重做
    save: true, // 保存
    /* v0.2.3 */
    subfield: true, // 单双栏模式
  };

  // 保存Markdown文本内容
  const [mdContent, setMdContent] = useState('')

  // 上传图片
  function uploadImg (file) {
    
    
    console.log('file', file);
  };
  // 输入内容改变
  function handleEditorChange (value) {
    
    
    console.log('handleChange', value);
    setMdContent(value)
  }
  // 保存输入内容
  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;

页面效果:
在这里插入图片描述

预览 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'
// 设置高亮样式
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-katexremark-math 展示数学公式

使用 rehype-katexremark-math 可以轻松的翻译输入的数学公式。

注意:需要使用 katex.css 来展示相应的效果,否则会出现公式乱掉的 BUG

index.html 中引入公式解析样式文件:

<!-- 解析Markdown数学公式样式 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/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

页面效果:
在这里插入图片描述

相关链接

react-markdown github 源码
for-editor github
markdown-navbar github

猜你喜欢

转载自blog.csdn.net/HH18700418030/article/details/130267813
今日推荐