阅读 522

vue/react 中实现 markdown 文件解析+目录(vue教程)

前言

最近有一个需求要把markdown文件展示到页面中,并且带目录。看了一些插件,把实践方法记录一下。

目标:

  1. 把 markdown 文件展示到页面中。

  2. 要根据标题展示 markdown 目录。

  3. 要有一些简单美观的 markdown 样式。

先介绍一下这些插件:

  • marked  只用于解析 Markdown,无样式,无目录。

  • highlight.js 用于代码颜色高亮

  • markdown-navbar 用于生成目录,适用于react

  • github-markdown-css github 风格的 markdown 样式

  • vue-markdown 适用于 Vue 的强大且高速的 Markdown 解析器。有样式有目录。

最开始想到的是用 marked + highlight.js 实现,但是 marked 插件无法生成目录,目录需要再用 markdown-navbar 插件辅助实现。然而 markdown-navbar 仅适用于 react 。所以我这里会写两种方法:

  • 方法一:在 react项目中 用 marked + highlight.js + markdown-navbar 实现解析+目录。

  • 方法二:在 vue项目中 用 vue-markdown 实现解析+目录。

虽然 vue-markdown 自带样式,但是我觉得 github-markdown-css 的样式顺眼一点,所以这两种方法中都是用的 github-markdown-css 样式。

marked + highlight.js + markdown-navbar

先看一下实现效果:

react-markdown.gif

其实 markdown-navbar 这个插件生成的目录非常完美,奈何只能用于 react 。marked 和 highlight.js 哪里都可以用没有限制,可以外链,可以npm。

github-markdown-css 文件我是直接放的css外链,当然也可以使用npm的方式添加。

注意:页面结构样式还是需要自己写的。

代码如下:

import React, { Component } from 'react'; import './App.css'; import ReactMarkdown from 'react-markdown'; import MarkNav from 'markdown-navbar'; import 'markdown-navbar/dist/navbar.css'; class App extends Component {   constructor(props) {     super(props)     this.state = {       markdown: ''     }   }   render() {     return (       <div className="App">         <div className="leftSide">             <h3 className="navTitle">文章目录</h3>             <MarkNav               className="toc-list"               source={this.state.markdown}               ordered={false}             />           </div>         <div className="content">           <div className="inputDv">             <input type="file" accept=".md" onChange={this.getFileInfo.bind(this)} />           </div>           <div className="markdown-body">             <ReactMarkdown               children={this.state.markdown}               escapeHtml={false}             />           </div>                    </div>       </div>     );   }   getFileInfo(event){     let _that = this;     // 获取 input file 对象     const resultFile = event.target.files[0];     if(resultFile){       // 使用 FileReader 方法读取文件       let reader = new FileReader();       // 读取纯文本文件,且编码格式为 utf-8       reader.readAsText(resultFile, 'UTF-8');       // 读取文件,会触发 onload 异步事件,可使用回调函数来获取最终的值       reader.onload = function (e) {         _that.setState({           markdown:e.target.result         })       }     }   } } export default App; 复制代码

vue-markdown

官方效果地址:VueMarkdown Live Demo

实现效果如下:

vue-markdown.gif

vue-markdown 这个插件功能还是挺全面的,有目录有样式,但是目录那块,没有 markdown-navbar 的功能那么全面,比如点击没有高亮样式,也不能随着滚动切换高亮效果,也有可能是我文档没看明白,文档中有很多选项,有兴趣的小伙伴可以自己去看一下文档。

代码如下:

<!DOCTYPE html> <html> <head>   <title>vue-markdown</title>   <meta charset="UTF-8">   <meta name="viewport" content="width=device-width, initial-scale=1">   <!-- github-markdown-css markdown 样式 -->   <link rel="stylesheet" href="https://unpkg.com/github-markdown-css@5.0.0/github-markdown.css">   <!-- 自定义布局样式 -->   <link rel="stylesheet" href="../css/markdown.css"> </head> <body>   <div id="app">     <div class="left-navSide">       <h3 class="nav-title">文章目录</h3>       <div class="nav-list" id="toc"></div>     </div>     <div class="right-content markdown-body">       <vue-markdown          :source="source"          :toc="true"          toc-id="toc"         :toc-first-level="2"         :toc-last-level="3"         v-on:toc-rendered="tocAllRight"       />     </div>   </div>   <script src="https://miaolz123.github.io/vue-markdown/dist/js/vue.js"></script>   <script src="https://miaolz123.github.io/vue-markdown/dist/vue-markdown.min.js"></script>   <script>     Vue.use(VueMarkdown)     let vm = new Vue({       el:'#app',       data() {         return {           source:'',         }       },       created:function(){         this.loadXMLDoc()       },       methods:{         loadXMLDoc(){           var $this = this;           var xmlhttp = new XMLHttpRequest();           xmlhttp.onreadystatechange=function()           {             if (xmlhttp.readyState==4 && xmlhttp.status==200)             {               // console.log(xmlhttp.responseText)               $this.source = xmlhttp.responseText;             }           }           xmlhttp.open("GET","../file/test.md",true);           xmlhttp.send();         }       }     })   </script> </body> </html> 复制代码

结语

总结一下,如果不需要目录,直接用 marked 解析 markdown,github-markdown-css 作样式就可以了。

如果需要目录,react 中 markdown-navbar 的目录功能能全面。vue 中 vue-markdown 这一个插件就足够了,目录和样式他都有,只是目前来看细节的地方不是那么完善,但是也够用了。

以上这些插件和实现效果是我尝试过的,当然还有其他插件可以实现同等的效果,欢迎探讨。


作者:1023
链接:https://juejin.cn/post/7028826246616350728

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐