支持 markdown 的折叠面板
首先看看看效果:
怎么样,还不错吧。Collapse 中支持了 markdown 语法的解析,表达能力更加丰富,这样的折叠面板可以有多种用途,比如给一道笔试题,结果就可以放在这里面,以防不小心瞄到~ 亦或是一些解释性、拓展性的内容也可以放在折叠面板里,来让页面变得整洁。
#
实现实现主要是使用了 antd 提供的 Collapse 组件以及一款 markdown 语法解析组件 react-markdown
另外,若需要在 react 项目中添加 markdown 编辑组件,可以使用 for-editor
Collapse 和 react-markdown 组件有多个可选配置,这边就介绍一下能够实现上面效果的最基本配置。
首先,安装依赖:
cnpm i --save react-markdown
cnpm i --save antd
cnpm i --save remark-gfm
cnpm i --save react-syntax-highlighter
其中,remark-gfm
插件用于提供更加丰富的 markdown
解析功能,比如删除线、表格、任务列表、URL 链接等等。
react-syntax-highlighter
正如正面意义,用于提供代码高亮的效果,有多种风格选择(效果),像上面展示的代码高亮风格是 darcula
。
组件封装:
import React from 'react';import ReactMarkdown from 'react-markdown';import gfm from 'remark-gfm';import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';import { darcula } from 'react-syntax-highlighter/dist/esm/styles/prism';import { Collapse } from 'antd';const { Panel } = Collapse;
// 从 markdwon 文件中解析出 代码段,并进行样式高亮处理,style 可以替换成自己喜欢的代码高亮风格const components = { code({node, inline, className, children, ...props}) { const match = /language-(\w+)/.exec(className || '') return !inline && match ? ( <SyntaxHighlighter style={darcula} language={match[1]} PreTag="div" children={String(children).replace(/\n$/, '')} {...props} /> ) : ( <code className={className} {...props} /> ) }}
// markdown 为需要解析的 markdown 文档, header 为 Collapse header 所展示的文字,OtherComponents 用于拓展折叠面板中的内容export default function CollapseWithMarkdown({ markdown, header, OtherComponents }) {
return ( <Collapse bordered={false}> <Panel header={header}> <ReactMarkdown components={components} children={`${markdown}`} remarkPlugins={[gfm]} /> { OtherComponents ? <OtherComponents /> : null } </Panel> </Collapse> );}
组件封装代码很简洁,各种轮子使用起来也很方便,不过在本博客中,向组件中传入 markdown 文本时却不那么方便了。
来看看文章开头实现效果的对应代码:
<MarkdownInCollapse markdown={` # title1
URL: https://reactjs.org. ~~~js var a = 3; console.log(a); ~~~ - abc - de
~strikethrough~
* Lists * [ ] todo * [x] done A table: | a | b | | - | - | `} header="点击查看效果👇" />
由于文章是在 markdown 文件中写的,而 markdown 对于一些字符会先进行解析,解析出的内容才会作为文本传入 MarkdownInCollapse 组件中,因此正常写的话很多地方会报错,因此写起来畏手畏脚的也不方便。
另一个替代方案就是:将当前需要传入 MarkdownInCollapse 组件中的字符串在另一个 JS 文件中写好,再使用 import 导入使用,这样就方便多啦,如:
const text = `.....`;
export default { text};