Code前端首页关于Code前端联系我们

Vue2 怎么实现 Markdown 渲染?从基础到进阶全解析

terry 3小时前 阅读数 6 #Vue
文章标签 Vue2;Markdown渲染

在 Vue2 项目里做博客、文档系统,或者让用户用 Markdown 写内容时,怎么把 Markdown 文本转成好看的 HTML 展示?这篇文章从“选啥工具”“咋基础实现”到“进阶优化”,一步步讲清楚 Vue2 里 Markdown 渲染的门道~

Vue2 项目里为啥要做 Markdown 渲染?

你想啊,现在很多场景都需要 Markdown:团队内部写技术文档,用 Markdown 更高效;做个人博客,写文章用 Markdown 排版省心;甚至社区论坛让用户发帖,用 Markdown 能避免复杂的富文本操作,但浏览器不认识 Markdown 语法啊,得把它转成 HTML 才能正常显示样式,Vue2 项目里得做“Markdown 转 HTML 并渲染”这件事,既让内容创作者写得爽,也让读者看得舒服。

Vue2 常用的 Markdown 渲染库有哪些?

常用的有三类,各有特点:

  • marked.js:轻量级选手,API 简单,上手快,适合只需要“把 Markdown 转成 HTML”的基础需求,比如简单文档展示,体积小,不拖项目后腿。
  • markdown-it:扩展性狂魔,生态里插件超级多(代码高亮、生成目录、流程图解析…),如果项目需要复杂功能,选它准没错。
  • vue-markdown:Vue 专用组件,把 Markdown 渲染封装成组件,直接在模板里用 <vue-markdown> 标签就行,适合想少写代码、快速集成的场景。

怎么选适合自己项目的 Markdown 渲染方案?

得看项目需求和团队情况:

  • 需求简单(只渲染标题、列表、段落):选 marked.js,体积小、配置少,几行代码就能跑起来。
  • 需求复杂(要代码高亮、自定义语法、图片/链接处理):选 markdown-it,靠插件扩展功能,想加啥功能都能找到现成的。
  • 想少写代码:用 vue-markdown 组件,开箱即用,连 v-html 都不用自己写,但如果后期要深度定制,可能没 markdown-it 灵活。
    另外还要考虑项目体积(marked.js 比 markdown-it 小)、团队技术熟练度(比如团队熟悉 Vue 组件写法,就优先 vue-markdown)这些因素。

Vue2 里用 marked.js 实现基础渲染步骤是啥?

分三步,还要注意 XSS 风险:

  1. 装依赖:终端执行 npm install marked
  2. 组件里用 marked:在 Vue 组件中引入 marked,写个方法把 Markdown 字符串转成 HTML。
    <template>
    <div v-html="renderedHtml"></div>
    </template>
``` 3. **防 XSS 攻击**:直接用 `v-html` 渲染用户输入的内容,容易被注入脚本,得用 `DOMPurify` 过滤危险代码,安装 `npm install dompurify`,然后修改代码: ```vue import DOMPurify from 'dompurify' // ... computed: { renderedHtml() { const html = marked(this.markdownContent) return DOMPurify.sanitize(html) // 净化后再渲染 } } ```

用 markdown-it 怎么实现更灵活的渲染(比如代码高亮)?

markdown-it 本身不自带代码高亮,得结合 highlight.js 这类库,步骤如下:

  1. 装依赖npm install markdown-it highlight.js
  2. 配置 markdown-it 和代码高亮:在组件里创建 markdown-it 实例,设置代码高亮的逻辑。
    <template>
    <div v-html="renderedHtml"></div>
    </template>
``` 这样代码块就会有漂亮的高亮样式了,如果需要其他功能(比如生成目录),搜 markdown-it 的插件(如 `markdown-it-toc-done-right`),装了之后配置到 markdown-it 实例里就行。

Vue 专用组件 vue-markdown 怎么快速集成?

适合想“零配置”用起来的同学,步骤很简单:

  1. 装依赖npm install vue-markdown
  2. 组件里用:引入后当普通 Vue 组件用,直接传 Markdown 内容。
    <template>
    <vue-markdown :source="markdownContent" :options="{ highlight: myHighlight }"></vue-markdown>
    </template>
``` vue-markdown 内部帮你处理了 `v-html` 和内容解析,还能通过 `options` 传配置(比如代码高亮、是否转义特殊字符),但如果要做特别定制化的操作(比如修改图片渲染逻辑),可能不如 markdown-it 灵活。

Markdown 渲染后的样式怎么自定义?

分两种情况:库默认样式自己写 CSS

  • 像 marked.js、markdown-it 这类库,默认渲染出的 HTML 是“裸”的,没有样式,得自己写 CSS 美化,比如给标题、列表、代码块加样式:
    /* 全局的 markdown 样式文件 */
    .markdown h1 {
    font-size: 28px;
    margin-bottom: 16px;
    color: #333;
    }
    .markdown p {
    line-height: 1.8;
    margin: 8px 0;
    }
    .markdown code {
    background: #f9f9f9;
    padding: 2px 4px;
    border-radius: 4px;
    }

    然后在渲染的容器上加 class="markdown",让样式生效。

  • 如果用了代码高亮(highlight.js),它的样式由引入的主题决定(atom-one-light.css),要是觉得主题不好看,可以自己写 CSS 覆盖 .hljs 开头的类名。
    在 Vue 组件里写样式时,如果用了 <style scoped>,要修改子组件或第三方库的样式,得用深度选择器
    <style scoped>
    .my-markdown >>> h2 {
    color: #444;
    }
    </style>

处理 Markdown 里的图片、链接有啥技巧?

图片处理

  • 统一加路径前缀:Markdown 里的图片是相对路径,想转成 CDN 地址,可以在渲染前替换字符串。
    const rawMd = '![示例](images/demo.png)'
    const cdnMd = rawMd.replace(/!\[(.+?)\]\((images\/.+?)\)/g, '![$1](https://cdn.example.com/$2)')
  • 用 markdown-it 插件markdown-it-linkify-images 能自动给图片加链接,或者写自定义渲染规则,修改图片标签的生成逻辑。

链接处理

  • 外部链接开新窗口:用户点外部链接时,希望在新窗口打开,还得加 rel="noopener noreferrer" 防止安全问题,用 markdown-it 重写链接的渲染规则:
    import md from 'markdown-it'
    const renderer = md()
    // 重写 link_open 规则
    const defaultLinkRender = renderer.renderer.rules.link_open || function(tokens, idx, opts, env, self) {
    return self.renderToken(tokens, idx, opts)
    }
    renderer.renderer.rules.link_open = function(tokens, idx, opts, env, self) {
    const href = tokens[idx].attrGet('href')
    if (href && href.startsWith('http')) { // 判断是否外部链接
      tokens[idx].attrSet('target', '_blank')
      tokens[idx].attrSet('rel', 'noopener noreferrer')
    }
    return defaultLinkRender(tokens, idx, opts, env, self)
    }

    这样渲染出来的外部链接,自动带 target="_blank" 和安全属性。

Vue2 Markdown 渲染遇到 XSS 攻击风险咋解决?

前面提过用 DOMPurify 过滤,这里再详细说场景和配置。

  • 场景:Markdown 内容是用户生成的(比如论坛发帖),恶意用户可能在 Markdown 里写 <script>alert(1)</script>,转成 HTML 后会执行脚本。
  • 解决步骤
    1. DOMPurifynpm install dompurify
    2. 在 Markdown 转 HTML 后,用 DOMPurify 净化:
      import DOMPurify from 'dompurify'
      // 假设 html 是 Markdown 转后的 HTML 字符串
      const cleanHtml = DOMPurify.sanitize(html)
    3. 高级配置:如果想允许某些标签/属性(比如自己项目里需要 <iframe> 嵌入视频),可以自定义配置:
      const config = {
      ALLOWED_TAGS: ['iframe', 'img', 'p', 'h1', 'h2'], // 允许的标签
      ALLOWED_ATTR: {
      iframe: ['src', 'width', 'height'] // 允许 iframe 的属性
      }
      }
      const cleanHtml = DOMPurify.sanitize(html, config)

      这样既保留业务需要的标签,又过滤危险内容。

大型项目里 Markdown 渲染的性能优化怎么做?

Markdown 内容特别长(比如几万字的文档),解析和渲染会变慢,得优化:

  • 缓存解析结果:用 computedvuex 缓存解析后的 HTML,相同内容不重复解析。
    computed: {
    renderedHtml() {
      if (this.cache[markdownContent]) {
        return this.cache[markdownContent]
      }
      const html = md.render(markdownContent)
      this.cache[markdownContent] = html
      return html
    }
    }
  • 异步解析:把 Markdown 解析放到 setTimeout 或 Web Worker 里,避免阻塞主线程,比如用 Web Worker:
    // main.js
    const worker = new Worker('markdown-worker.js')
    worker.postMessage(markdownContent)
    worker.onmessage = (e) => {
    this.renderedHtml = e.data
    }

// markdown-worker.js importScripts('path/to/markdown-it.js') const md = require('markdown-it')() self.onmessage = (e) => { const html = md.render(e.data) self.postMessage(html) }

- **分片渲染**:如果内容超长,把 HTML 分成多段,用 `v-if` 分批渲染,减少首屏加载压力。  
### Vue2 升级到 Vue3 后 Markdown 渲染有啥变化?  
核心的 Markdown 解析库(marked、markdown-it)用法不变,但 Vue 组件写法有变化:  
- **Composition API**:Vue3 用 `setup` 语法糖,代码组织更集中,比如用 markdown-it 时,逻辑可以写到 `setup` 里:  
```vue
<script setup>
import md from 'markdown-it'
import { computed } from 'vue'
const markdownContent = '# Vue3 里的 Markdown'
const renderedHtml = computed(() => md().render(markdownContent))
</script>
<template>
  <div v-html="renderedHtml"></div>
</template>
  • 组件兼容性:如果之前用 vue-markdown,Vue3 得换对应的库(vue3-markdown),要注意版本兼容。
    Markdown 渲染的“逻辑”没变,只是 Vue 组件的写法更灵活了。

从选库到基础实现,再到样式、安全、性能这些细节,Vue2 里做 Markdown 渲染其实没那么复杂~根据自己项目需求挑对工具,再把细节(XSS、代码高亮)处理好,用户就能舒舒服服写 Markdown,读者也能看到美观的排版啦~要是你在实践中遇到其他问题,比如插件怎么自定义、移动端样式适配,评论区聊聊呀~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门