1.Markdown介绍
1.1 Markdown是什么
Markdown是一种轻量级标记语言,创始人是约翰·格鲁伯(John Gruber)。它允许人们 “使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档。
1.2 Markdown的基本语法
Markdown的语法简洁明了、学习容易,而且功能比纯文本更强,因此有很多人用它写博客。世界上最流行的博客平台WordPress和大型CMS如joomla、drupal都能很好的支持Markdown,Github也是支持markdown的,在个性化语法上也做了不少的改进。Markdown的中文语法介绍:事例
1.3 Markdown 编辑器工具
2.MarkDwon解析方法有哪些?
但Markdown不是HTML,目前还不能被浏览器解析,所以我们需要Markdown的解析器,把Markdown翻译成浏览器认识的HTML文档展示出来。
在 Github
上查找关于如何在 React
实现 markdown
的渲染,查到了这两种库:
第一种:react-markdown
https://github.com/rexxars/react-markdown
第二种:marked+highlight.js
https://github.com/markedjs/marked
Marked就是一个基于Nodejs的Markdown解析引擎!
3.MarkDwon解析的具体操作
3.1 插件安装
npm install marked --save npm install highlight.js --save
①marked插件
一款最受欢迎的markdown文件解析插件。
插件地址:https://github.com/chjj/marked
②highlight.js插件
格式化显示各种语言的前端插件,用于解析文档中代码部分。
插件地址:https://highlightjs.readthedocs.io/en/latest/css-classes-reference.html
3.2 引入模块
引入这两个插件及
highlight.js
样式文件
import marked from 'marked' import hljs from 'highlight.js' import 'highlight.js/styles/atom-one-dark.css'
3.3 设置参数
const renderer = new marked.Renderer(); // marked插件的基础设置 marked.setOptions({ renderer: renderer, gfm: true, tables: true, breaks: false, pedantic: false, sanitize: false, smartLists: true, smartypants: false, xhtml: false, highlight: function (code) { // 使用highlight 插件解析文档中代码部分,可直接设置高亮显示 return hljs.highlightAuto(code).value; } });
参数说明:
renderer
: 这个是必须填写的,你可以通过自定义的Renderer
渲染出自定义的格式gfm
:启动类似Github样式的Markdown,填写true或者falsetables
: 支持Github形式的表格,必须打开gfm选项,填写true或者falsebreaks
: 支持Github换行符,必须打开gfm选项,填写true或者falsepedantic
:只解析符合Markdown定义的,不修正Markdown的错误。填写true或者falsesanitize
: 原始输出,忽略HTML标签,默认为false
。 对输出进行过滤(清理),将忽略任何已经输入的html代码(标签)smartLists
:优化列表输出,这个填写ture之后,你的样式会好看很多,所以建议设置成turehighlight
: 高亮显示规则 ,这里我们将使用highlight.js来完成
同时搭配highlight.js代码高亮使用
在设置setOptions
属性时,可以直接设置高亮显示,代码如下:
highlight: function (code) { return hljs.highlightAuto(code).value; }
highlight.js
是支持多种代码配色风格的,可以在css
文件中进行切换,高亮主题可以自己更换自己喜欢的:
import 'highlight.js/styles/atom-one-dark.css'
在这可以看到每种语言的高亮效果和配色风格:highlightjs.org/
在你未设置代码高亮时,代码部分也就是普通文本,展示如下:

设置完成后,你在浏览器检查代码时就可以出现hljs的样式,说明你的效果加成功了,实现了高亮显示代码。

以上操作完毕后就基本能够达到想要的效果了,如果觉得现在的样式不是很好看的话,可以自己继续设置一下样式,如果想让代码块突出显示的话 可以设置 pre code
标签的 css,我的设置如下:
/* 实现代码高亮 */ pre{ display: block; background-color:#f3f3f3; padding: .5rem !important; overflow-y: auto; font-weight: 300; border-radius: .3rem; background-color: #283646 !important; } pre >code{ border:0px !important; background-color: #283646 !important; color:#FFF; } code { display: inline-block ; background-color:#f3f3f3; border:1px solid #fdb9cc; border-radius:3px; font-size: 12px; padding-left: 5px; padding-right: 5px; color:#4f4f4f; margin: 0px 3px; }
3.4 markdown渲染
import marked from 'marked'; const input = '# This is a header\n\nAnd this is a paragraph'; const html = marked(input);
此时我们将html打印出来并看看他的类型
console.log(html,typeof(html)) <h1>This is a header</h1> <p>And this is a paragraph</p> string
上边的三步配置完后就可以通过 const html = marked(input)
的方式转换md 内容为html 并进行渲染了,但是需要注意的是在react 中直接对需要渲染的地方使用 dom.innerText=html
的方式进行渲染会渲染出marked 转化出的字符串,这不是我们想要的结果 ,需要强制将字符串转化为html 代码
React中标签字符串强制转html解析的方法
在
React
中我们经常会请求数据并渲染到页面中间显示,我们可以直接使用更新state的方法,并使用tihs.state.(data)的方法进行渲染,但是我们有时候会遇到需要渲染html
标签的字符串
到页面中如果直接进行渲染我们得到的是html字符串
,并不是我们想要的html标签
。这个时候我们应该怎么办呢?
1.js原生方法
var html="<p>这是需要渲染的标签字符串</p>" document.body.innerHTML = html
2.react中强制转为html解析的方法
在 React
中,我们可以这样做:
<div dangerouslySetInnerHTML={{ __html: html }} />
文章是用 markdown
语法写的,所以要先转成 html
然后插入页面中,这里用了一个 React
不提倡的属性:dangerouslySetInnerHTML
。
利用marked对文本进行编译,并将编译出来的 HTML
传入到dangerouslySetInnerHTML属性中
3.5自定义解析方法
const renderer = new marked.Renderer() renderer.table = (header, body) => { return '<table class="table table-bordered">'+header+body+'</table>' }
-
如:未设置表格解析方法前,表格无表格样式
-
设置后表格有自定义的样式
参数名称 | 是否必须 | 示例 | 备注 |
---|---|---|---|
version | 是 | 1.0.0 | 接口版本号 |
method | 是 | vivopay.h5.trade.create | 接口服务名称 |
timestamp | 是 | 20180724030750 | 发送请求的时间,格式:yyyyMMddHHmmss |
signType | 是 | RSA | 签名方式,暂定RSA |
sign | 是 | ALKHIKYQUIHLBNLAHKLHLHJL | 签名 |
appId | 是 | 2019002536451112 | 应用编号 |
bizContent | 是 | 可扩展的业务参数集合,格式为Json对象字符串 |
4.实现文章导航栏
4.1Tocify组件简介
这是我在网上找的一个文件,可以直接使用
tocify文件
import React from 'react'; import { Anchor } from 'antd'; import { last } from 'lodash'; const { Link } = Anchor; export interface TocItem { anchor: string; level: number; text: string; children?: TocItem[]; } export type TocItems = TocItem[]; // TOC目录树结构 export default class Tocify { tocItems: TocItems = []; index: number = 0; constructor() { this.tocItems = []; this.index = 0; } add(text: string, level: number) { const anchor = `toc${level}${++this.index}`; const item = { anchor, level, text }; const items = this.tocItems; if (items.length === 0) { // 第一个 item 直接 push items.push(item); } else { let lastItem = last(items) as TocItem; // 最后一个 item if (item.level > lastItem.level) { // item 是 lastItem 的 children for (let i = lastItem.level + 1; i <= 2; i++) { const { children } = lastItem; if (!children) { // 如果 children 不存在 lastItem.children = [item]; break; } lastItem = last(children) as TocItem; // 重置 lastItem 为 children 的最后一个 item if (item.level <= lastItem.level) { // item level 小于或等于 lastItem level 都视为与 children 同级 children.push(item); break; } } } else { // 置于最顶级 items.push(item); } } return anchor; } reset = () => { this.tocItems = []; this.index = 0; }; renderToc(items: TocItem[]) { // 递归 render return items.map(item => ( <Link key={item.anchor} href={`#${item.anchor}`} title={item.text}> {item.children && this.renderToc(item.children)} </Link> )); } render() { return ( <Anchor affix showInkInFixed> {this.renderToc(this.tocItems)} </Anchor> ); } }
4.2自定义使用方法
通过heading在标题处设置对应的锚点,这里就又涉及到自定义解析方法
const tocify = new Tocify(); const renderer = new marked.Renderer(); // 解析<h1>标签时需要将内容包裹在一个拥有特殊布局的<h1>标签中,并且不影响其他head标签的渲染 renderer.heading = function(text, level, raw) { const anchor = tocify.add(text, level); return `<h${level} id="${anchor}">${text}</h${level}>\n`; };
导航栏部分代码,可直接应用,生成后可实现点击到对应锚点标题处
<div className="details-nav"> <div className="toc-list"> {tocify && tocify.render()} </div> </div>