marked.js讲解

一、地址 mared.js

二、安装 npm install marked --save

三、设置参数

marked.setOptions({ renderer: new marked.Renderer(), gfm: true, tables: true, breaks: true, pedantic: false, sanitize: false, smartLists: true, smartypants: false, highlight(code) { return Hljs.highlightAuto(code).value } })

gfm 它是一个布尔值,默认为true。 允许 Git Hub标准的markdown.

tables 它是一个布尔值,默认为true。 允许支持表格语法。该选项要求 gfmtrue

breaks 它是一个布尔值,默认为false。 允许回车换行。该选项要求 gfmtrue

pedantic 它是一个布尔值,默认为false。 尽可能地兼容 markdown.pl的晦涩部分。不纠正原始模型任何的不良行为和错误。

sanitize 它是一个布尔值,默认为false。 对输出进行过滤(清理),将忽略任何已经输入的html代码(标签) smartLists 它是一个布尔值,默认为false。 使用比原生markdown更时髦的列表。 旧的列表将可能被作为pedantic的处理内容过滤掉.

smartypants 它是一个布尔值,默认为false。 使用更为时髦的标点,比如在引用语法中加入破折号。

四、自定义解析方法

const renderer = new marked.Renderer() const paragraphParse = text => `<p>${text}</p>` renderer.paragraph = paragraphParse return marked(content, { renderer })

转载于:https://juejin.im/post/5b11492fe51d4506c8664be1

<think>我们将使用Vue.js构建一个单页应用,实现以下功能:1.左边侧边栏显示指定文件夹下的所有.md文件(这里我们假设文件夹位于项目中的某个位置,但注意浏览器端JavaScript不能直接访问本地文件系统,因此需要后端支持)2.点击文件名,在右侧内容区域展示该.md文件的内容(转换为HTML)由于浏览器安全限制,前端JavaScript无法直接读取本地文件系统。因此,我们需要一个后端服务来提供文件列表和文件内容。这里我们使用Flask作为后端,Vue作为前端。项目结构: -后端(Flask):提供两个API接口1.获取文件列表:返回指定目录下的所有.md文件名2.获取文件内容:根据文件名返回.md文件的内容(转换为HTML) -前端(Vue):使用axios调用后端API,展示文件列表和文件内容。步骤:1.后端实现(Flask):-设置一个文件夹存放.md文件-提供`/api/files`接口返回文件列表-提供`/api/file/<filename>`接口返回指定文件的内容(转换为HTML)2.前端实现(Vue):-使用vue-router(可选,这里我们不需要多个路由,用动态组件即可)-左侧:使用v-for渲染文件列表,每个文件名绑定点击事件-右侧:展示当前选中的文件内容注意:由于涉及跨域,我们可以在Flask端配置CORS,或者将Vue构建的静态文件放在Flask的静态文件夹中一起部署。这里为了开发方便,我们使用CORS。详细代码:后端(Flask)代码:首先,安装必要的库: ```bashpip installflask flask-corsmarkdown```创建`server.py`:</think>下面我将详细讲解如何使用Vue.js实现一个带目录导航的Markdown阅读器应用,左侧显示文件夹中的所有.md文件,点击后在右侧展示内容。 ### 解决方案设计思路 1. **前端架构**:Vue.js + Vue Router + Axios 2. **目录结构**: - 左侧:文件树组件 - 右侧:Markdown渲染组件 3. **核心功能**: - 读取本地文件夹结构 - 动态加载Markdown文件 - 实时渲染Markdown内容 ### 完整代码实现 #### 1. 项目结构 ```bash markdown-reader/ ├── public/ │ └── markdown/ # 存放.md文件的文件夹 │ ├── doc1.md │ ├── doc2.md │ └── subfolder/ │ └── doc3.md ├── src/ │ ├── components/ │ │ ├── FileTree.vue # 文件树组件 │ │ └── MarkdownViewer.vue # Markdown渲染组件 │ ├── App.vue │ ├── main.js │ └── router.js └── vue.config.js # 配置静态资源 ``` #### 2. 配置vue.config.js ```javascript module.exports = { publicPath: './', assetsDir: 'static', devServer: { // 代理解决跨域问题 proxy: { '/markdown': { target: 'http://localhost:8080', pathRewrite: { '^/markdown': '' } } } } } ``` #### 3. 文件树组件 (FileTree.vue) ```vue <template> <div class="file-tree"> <ul> <li v-for="item in fileList" :key="item.path"> <div @click="selectFile(item)" :class="{ 'is-folder': item.isFolder, 'selected': selectedFile === item }" > <span v-if="item.isFolder">📁</span> <span v-else>📄</span> {{ item.name }} </div> <FileTree v-if="item.isFolder && item.expanded" :fileList="item.children" @file-selected="handleFileSelected" /> </li> </ul> </div> </template> <script> export default { name: 'FileTree', props: { fileList: Array }, data() { return { selectedFile: null } }, methods: { selectFile(item) { if (item.isFolder) { item.expanded = !item.expanded } else { this.selectedFile = item this.$emit('file-selected', item) } }, handleFileSelected(file) { this.$emit('file-selected', file) } } } </script> <style scoped> .file-tree { padding: 10px; height: 100vh; overflow-y: auto; background: #f5f5f5; border-right: 1px solid #ddd; } ul { list-style: none; padding-left: 20px; } li { margin: 5px 0; cursor: pointer; } div { padding: 5px; border-radius: 4px; } div:hover { background: #e9e9e9; } .selected { background: #d6eaff; font-weight: bold; } .is-folder { font-weight: bold; } </style> ``` #### 4. Markdown渲染组件 (MarkdownViewer.vue) ```vue <template> <div class="markdown-viewer"> <div v-if="loading" class="loading">Loading...</div> <div v-else-if="error" class="error">{{ error }}</div> <div v-else class="content markdown-body" v-html="compiledMarkdown"></div> </div> </template> <script> import axios from 'axios' import marked from 'marked' import hljs from 'highlight.js' export default { name: 'MarkdownViewer', props: ['filePath'], data() { return { markdownContent: '', loading: false, error: null } }, computed: { compiledMarkdown() { // 配置Markdown解析器 marked.setOptions({ highlight: (code, lang) => { const language = hljs.getLanguage(lang) ? lang : 'plaintext' return hljs.highlight(code, { language }).value }, pedantic: false, gfm: true, breaks: false, sanitize: false }) return marked(this.markdownContent) } }, watch: { filePath: { immediate: true, handler(newPath) { if (newPath) { this.loadMarkdownFile(newPath) } } } }, methods: { async loadMarkdownFile(path) { this.loading = true this.error = null try { // 从public/markdown目录获取文件 const response = await axios.get(`/markdown/${path}`) this.markdownContent = response.data } catch (err) { this.error = `无法加载文件: ${err.message}` console.error('加载Markdown文件失败:', err) } finally { this.loading = false } } } } </script> <style scoped> .markdown-viewer { padding: 20px; height: 100vh; overflow-y: auto; } .content { max-width: 800px; margin: 0 auto; } .loading, .error { text-align: center; padding: 20px; color: #666; } </style> ``` #### 5. 主应用组件 (App.vue) ```vue <template> <div class="app-container"> <div class="sidebar"> <FileTree :fileList="fileTree" @file-selected="handleFileSelected" /> </div> <div class="content"> <MarkdownViewer :filePath="currentFilePath" /> </div> </div> </template> <script> import FileTree from './components/FileTree.vue' import MarkdownViewer from './components/MarkdownViewer.vue' export default { components: { FileTree, MarkdownViewer }, data() { return { fileTree: [], currentFilePath: '' } }, mounted() { // 获取文件树结构 this.fetchFileTree() }, methods: { async fetchFileTree() { try { const response = await axios.get('/markdown/file-tree.json') this.fileTree = response.data } catch (err) { console.error('获取文件树失败:', err) } }, handleFileSelected(file) { this.currentFilePath = file.path } } } </script> <style> .app-container { display: flex; height: 100vh; } .sidebar { width: 300px; min-width: 250px; overflow: auto; } .content { flex: 1; overflow: auto; } </style> ``` #### 6. 生成文件树结构 (file-tree-generator.js) ```javascript const fs = require('fs') const path = require('path') function generateFileTree(dir, basePath = '') { const result = [] const files = fs.readdirSync(dir) files.forEach(file => { const fullPath = path.join(dir, file) const relativePath = path.join(basePath, file) const stats = fs.statSync(fullPath) if (stats.isDirectory()) { result.push({ name: file, path: relativePath, isFolder: true, expanded: false, children: generateFileTree(fullPath, relativePath) }) } else if (path.extname(file) === '.md') { result.push({ name: file, path: relativePath, isFolder: false }) } }) return result } // 生成public/markdown目录的文件树 const tree = generateFileTree(path.join(__dirname, 'public', 'markdown')) fs.writeFileSync( path.join(__dirname, 'public', 'markdown', 'file-tree.json'), JSON.stringify(tree, null, 2) ) console.log('文件树已生成!') ``` ### 关键功能说明 1. **文件树生成**: - 使用Node.js脚本扫描`public/markdown`目录 - 生成包含文件和文件夹结构的JSON文件 - 在应用启动时加载该JSON文件 2. **文件加载**: - 使用Axios获取Markdown文件内容 - 通过Vue的watch机制监听文件路径变化 - 添加加载状态和错误处理 3. **Markdown渲染**: - 使用marked库将Markdown转换为HTML - 集成highlight.js实现代码语法高亮 - 使用GitHub风格的CSS样式 4. **组件交互**: - 文件树组件使用递归组件实现嵌套结构 - 通过事件总线传递文件选择事件 - 响应式更新右侧内容区域 ### 使用说明 1. 创建项目: ```bash vue create markdown-reader cd markdown-reader npm install axios marked highlight.js ``` 2. 创建文件树生成脚本: ```bash node file-tree-generator.js ``` 3. 添加样式: ```bash npm install github-markdown-css ``` 在`main.js`中添加: ```javascript import 'github-markdown-css' import 'highlight.js/styles/github.css' ``` 4. 运行应用: ```bash npm run serve ``` ### 优化建议 1. **性能优化**: - 添加文件内容缓存 - 实现虚拟滚动处理大型文件树 - 使用Web Worker处理Markdown解析 2. **功能增强**: - 添加搜索功能 - 实现文件收藏/书签 - 支持Markdown编辑模式 - 添加目录大纲导航 3. **错误处理**: - 文件不存在处理 - 网络错误重试机制 - 空状态提示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值