React Markdown 編輯及渲染解決方案

前言

以前用的富文本編輯框,感受格式特別亂,寫出來的文章佈局根本沒眼看,代碼高亮也沒找到合適的。因此一直想着把富文本改成markdown。javascript

插件的選擇

咱們須要寫文章和看文章,因此得有markdown編輯器插件和markdown渲染插件。 github上有不少插件,我最終選定的是for-editorreact-markdown,前者用於編寫,後者用於加載。css

選擇好插件以後,讓咱們開始在項目中使用吧!java

for-editor 安裝使用方法

安裝

npm install for-editor --save
複製代碼

使用

代碼以下:react

import React from 'react'
import Editor from 'for-editor'

class WriteBlog extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      editorValue:'',
      imageUrl:''
    }
  }
  handleChange(value){
    this.setState({
      editorValue:value
    })
  }
  uploadHandler(params){
    fetch.get('getQiniuToken',{
      token:JSON.parse(Cookies.get('loginInfo')).token
    }).then(res=>{
      utils.uploadFile(params,res.data.qiniuToken).then(res=>{
        this.setState({
          imageUrl:'http://img.xuweijin.com/'+res
        })
        let str = this.state.editorValue + '![alt](http://img.xuweijin.com/'+res+')'
        this.setState({
          editorValue:str
        })
      })
    })
  }
  render(){
    return(
      <Editor className="my-editor" subfield = {true} preview = {true} addImg = {(file) => this.uploadHandler(file)} value={this.state.editorValue} onChange={(value) => this.handleChange(value)} /> ) } 複製代碼

圖片上傳沒有使用官方的方法,上傳成功手動往編輯器里加入圖片的字符串。git

上面只是簡單貼了一些代碼,具體參數請直接前往for-editor github主頁查看。github

react-markdown 安裝使用辦法

安裝

npm install --save react-markdown
複製代碼

使用

代碼以下:shell

import React from 'react'
import ReactMarkdown from 'react-markdown'
class BlogDetail extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      articleDetail:'',
    }
  }
  render(){
    return(
      <ReactMarkdown source={this.state.articleDetail.article_content} escapeHtml={false}></ReactMarkdown>
    )
  }
}
複製代碼

上面只是簡單貼了代碼,具體配置參數請前往github react-markdown主頁查看。npm


以上就是markdown文本的解決辦法,但到此還不算結束,咱們解析時還要加上代碼高亮,不然當咱們文章裏有代碼時,閱覽體驗將會極差。sass

代碼高亮

安裝代碼高亮插件包

我這邊選擇的是_react-syntax-highlighter_markdown

npm install react-syntax-highlighter --save
複製代碼

使用

  1. 首先新建一個CodeBlock.jsx文件,代碼以下
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import { PrismLight as SyntaxHighlighter } from "react-syntax-highlighter";
// 設置高亮樣式
import { xonokai } from "react-syntax-highlighter/dist/esm/styles/prism";
// 設置高亮的語言
import { jsx, javascript, sass, scss } from "react-syntax-highlighter/dist/esm/languages/prism";
class CodeBlock extends PureComponent {
  static propTypes = {
    value: PropTypes.string.isRequired,
    language: PropTypes.string
  };

  static defaultProps = {
    language: null
  };

  componentWillMount() {
    // 註冊要高亮的語法,
    // 注意:若是不設置打包後供第三方使用是不起做用的
    SyntaxHighlighter.registerLanguage("jsx", jsx);
    SyntaxHighlighter.registerLanguage("javascript", javascript);
    SyntaxHighlighter.registerLanguage("js", javascript);
  }

  render() {
    const { language, value } = this.props;
    return (
      <figure className="highlight"> <SyntaxHighlighter language={language} style={xonokai}> {value} </SyntaxHighlighter> </figure>
    );
  }
}
export default CodeBlock;
複製代碼
  1. 解析時使用

根據react-markdown提供的方法,咱們在解析md文件是,對code標籤進行處理,加入高亮的樣式類名,簡單貼下代碼:

import CodeBlock from '../components/CodeBlock'
class BlogDetail extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      articleDetail:'',
    }
  }
  render(){
    return(
      <ReactMarkdown source={this.state.articleDetail.article_content} renderers={{ code: CodeBlock }} escapeHtml={false}></ReactMarkdown>
    )
  }
}
複製代碼

這樣咱們就能夠看到文章解析時,代碼部分會出現高亮樣式了。

文章目錄

當咱們文章過長時,咱們須要加入文章目錄以便讀者對總體有個概覽,也方便讀者迅速切換到想要了解的部分,相似於掘金這種

alt

經過github,最後找到markdown-navbar這個插件,雖然star數很少,可是使用起來仍是很方便的。

markdown-navbar 安裝

npm install markdown-navbar --save
複製代碼

使用

這個插件使用起來仍是很方便的,只須要在項目中引入這個插件,而後把須要解析的md文件傳入,就會自動生成一個目錄樹。通常目錄樹須要固定,因此我這裏使用了antd的Anchor組件,將目錄固定在了右側,代碼以下:

import { Anchor } from 'antd';
import MarkNav from 'markdown-navbar';
import 'markdown-navbar/dist/navbar.css';
class BlogDetail extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      articleDetail:'',
    }
  }
  render(){
    return(
      <Anchor> <div className="markNav-title">文章目錄</div> <MarkNav className="article-menu" source={this.state.articleDetail.article_content} headingTopOffset={80} /> </Anchor> ) } } 複製代碼

這裏只是簡單貼了代碼,具體配置還請前往github markdown主頁自行查看。

結論

以上就是react markdown語法編輯及渲染總體的解決方案啦,貼一張渲染後的文章圖片:

alt

能夠看到渲染後的樣式仍是挺工整的,大功告成!

第一次寫這種小長篇,基本都是流水帳的形式,很是感謝您能看到最後,最後歡迎您來個人我的主頁留言互動~

相關文章
相關標籤/搜索