美文网首页
仿Github的markdown渲染效果

仿Github的markdown渲染效果

作者: percykuang | 来源:发表于2020-06-19 11:53 被阅读0次

安装依赖

  1. 添加markdown渲染
    yarn add react-markdown

  2. 实现代码高亮
    yarn add highlight.js

  3. 使用styled-components进行UI组件封装
    yarn add styled-components
    yarn add --dev @types/styled-components

CodeBlock组件

// index.css
code {
  font-family: "SFMono-Regular", "Consolas", "Liberation Mono", "Menlo", "monospace";
  border-radius: 3px;
  background-color: rgba(27,31,35,.05);
}
import React, { useEffect } from 'react'
import highLight from 'highlight.js'
// 主题文件:github、github-gist、color-brewer、railscasts、agate、atom-one-dark、rainbow、atom-one-light
import 'highlight.js/styles/github-gist.css'  //代码块样式
import './index.css'

interface IProps {
  value: string
  language: string
}

export default function (props: IProps) {

  const ref = React.createRef<HTMLElement>()

  useEffect(() => {
    if (ref.current) {
      highLight.highlightBlock(ref.current)
    }
  })

  return (
    <pre>
      <code ref={ ref } className={ `language-${ props.language }` }>
        { props.value }
      </code>
    </pre>
  )
}

修改github-gist.css文件

为了让显示效果更贴合Github的代码高亮显示,这里需要对highlight.js/styles/github-gist.css稍作修改,修改如下:

.hljs {
  display: block;
  /*background: white;*/
  /* 更改代码背景色 */
  background: #f6f8fa;
  /* 更改文字大小 */
  font-size: 90%;
  /* 设置行高 */
  line-height: 1.45;
  padding: 0.5em;
  color: #333333;
  overflow-x: auto;
}

Markdown组件

import React from 'react'
import ReactMarkdown from 'react-markdown/with-html'
import CodeBlock from './CodeBlock'
import styled from 'styled-components'

const Wrapper = styled.div`
  max-width: 1012px;
  margin: 12px auto;
  padding-right: 16px;
  padding-left: 16px;
  box-sizing: border-box;
  border-radius: 3px;
  border: 1px solid #eee;
`

interface IProps {
  content: string
}

function Markdown(props: IProps) {
  return (
    <Wrapper>
      <ReactMarkdown source={props.content} renderers={{code: CodeBlock}}/>
    </Wrapper>
  )
}

export default Markdown

App.tsx

import React from 'react';
import './App.css';
import Markdown from './components/article/Markdown'

const content = `
# React-Notes

## React 核心概念

### JSX

#### JSX是什么?

- Fackbook起草的JS扩展语法
- 本质是一个JS对象,会被babel编译,最终会被转换为\`React.createElement\`
- 每个JSX表达式,有且仅有一个根节点
  - React.Fragment(空节点相当于\`<></>\`)
- 每个JSX元素必须结束(XML规范)

\`\`\`jsx
<div className="App">
  <h1>hello</h1>
  <img />
</div>
\`\`\`



#### 在JSX中嵌入表达式

- 将表达式作为内容的一部分
  - false,null和undefined不会显示
  - 普通对象不可作为子元素
  - 可以放置React元素对象
- 将表达式作为元素属性
- 属性使用小驼峰命名法
- 防止注入攻击
  - 自动编码
  - \`dangerouslySetInnerHTML\`

使用:

\`\`\`jsx
function Me() {
  const person = { name: 'Flinn', friends: ['Leon', 'Monica'] }
  return (
    <div className="App">
      <h1>hello</h1>
      name: {person.name}
      <br />
      friends:
      <ul>{ person.friends.map(friend => <li>{friend}</li>) }</ul>
    </div>
  )
}
\`\`\`

通常情况下,为防止注入攻击,React使用innerText进行页面的渲染,如有特殊需求,可使用\`dangerouslySetInnerHTML\`改为innerHTML:

\`\`\`jsx
function App() {
  const content = '<h1>dangerous!!!</h1>'
  return (
    <div className="App" dangerouslySetInnerHTML={{__html: content}}>
    </div>
  )
}
\`\`\`

`


function App() {

  return (
    <div className="App">
      <Markdown content={content}/>
    </div>
  );
}

export default App;

预览结果

1.png

相关文章

网友评论

      本文标题:仿Github的markdown渲染效果

      本文链接:https://www.haomeiwen.com/subject/cudvxktx.html