如何在vue中渲染markdown内容?

文章目录

引言

在现代 Web 开发中,Markdown 作为一种轻量级的标记语言,广泛用于文档编写、内容管理以及富文本编辑器中。markdown-it 是一个非常流行的 JavaScript 库,用于解析和渲染 Markdown 内容。本文将详细介绍如何在 Vue 项目中使用 markdown-it 插件来渲染 Markdown 内容,并提供一些实用的配置和优化建议。


什么是 markdown-it?

markdown-it 是一个高度可配置的 Markdown 解析器,支持扩展和插件机制。它具有以下特点:

  • 高性能:快速解析和渲染 Markdown 内容。
  • 可扩展性:支持通过插件扩展功能。
  • 兼容性:支持 CommonMark 规范,并可配置以支持其他 Markdown 扩展。
  • 灵活性:可以轻松集成到各种 JavaScript 框架中,如 Vue、React 等。

安装 markdown-it

首先,我们需要在 Vue 项目中安装 markdown-it。你可以使用 npm 或 yarn 来安装:

bash 复制代码
npm install markdown-it

或者

bash 复制代码
yarn add markdown-it

基本用法

安装完成后,我们可以在 Vue 组件中使用 markdown-it 来解析和渲染 Markdown 内容。以下是一个简单的示例:

js 复制代码
<template>
  <div>
    <h1>Markdown 渲染示例</h1>
    <div class="markdown-body" v-html="markdownContent"></div>
  </div>
</template>

<script lang="ts" setup>
import markdownit from 'markdown-it'; 

  const md = markdownit();
 const markdownText = `
		# 标题
		
		这是一个简单的 Markdown 示例。
		
		- 列表项 1
		- 列表项 2
		- 列表项 3
		
		**粗体文本** 和 *斜体文本*
		
		\`\`\`javascript
		const hello = 'world';
		console.log(hello);
		\`\`\`
		    `;
  const markdownContent =  md.render(markdownText );   
</script>

<style>
/* 添加一些基本样式 */
.markdown-body {
  font-size: 16px;
  line-height: 1.6;
  color: #333;
}

.markdown-body h1 {
  font-size: 24px;
  margin-bottom: 10px;
}

.markdown-body ul {
  margin-left: 20px;
}

.markdown-body li {
  margin-bottom: 5px;
}

.markdown-body strong {
  font-weight: bold;
}

.markdown-body em {
  font-style: italic;
}

.markdown-body a {
  color: #007bff;
  text-decoration: none;
}

.markdown-body a:hover {
  text-decoration: underline;
}

.markdown-body pre {
  background-color: #f4f4f4;
  border-radius: 5px;
  padding: 10px;
  overflow-x: auto;
}

.markdown-body code {
  font-family: "Courier New", Courier, monospace;
  background-color: #f1f1f1;
  padding: 2px 6px;
  border-radius: 3px;
}
</style>

样式失效?

当在Vue的style标签中设置了scope属性,你会发现.markdown-body后面设置样式并不会生效,原因如下:

当你在 Vue 组件中使用 scoped 样式时,样式会被限制在当前组件内,以避免样式冲突。然而,使用 v-html 渲染的内容不会受到 scoped 样式的限制,因为 v-html 插入的内容是动态生成的,并且不会被 Vue 的作用域样式处理。这会导致 v-html 渲染的内容样式失效。

解决方法

有几种方法可以解决这个问题:

  1. 移除 scoped 样式:

    • 如果你希望样式对整个应用生效,可以移除 scoped 属性。
  2. 使用深度选择器:

    • 如果你必须使用 scoped 样式,vue3中可以使用深度选择器 :deep() 或 ::v-deep 来确保样式应用到 v-html 内容。
  3. 全局样式:

    • 将样式放在全局样式文件中,而不是组件的 style 部分。

高级配置

语法高亮

为了支持代码块的语法高亮,我们可以使用 markdown-it-highlightjs 插件。

  1. 安装插件:

    bash 复制代码
    npm install markdown-it-highlightjs highlight.js
  2. 配置插件:

    typescript 复制代码
    <template>
      <div>
        <h1>Markdown 渲染示例</h1>
        <div class="markdown-body" v-html="markdownContent"></div>
      </div>
    </template>
    
    <script>
    import markdownit from 'markdown-it';
    import hljs from 'highlight.js';
    import 'highlight.js/styles/default.css'; // 你可以选择其他样式
      const md = markdownit({
          highlight: function (str, lang) {
            if (lang && hljs.getLanguage(lang)) {
              try {
                return '<pre class="hljs"><code>' +
                       hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
                       '</code></pre>';
              } catch (__) {}
            }
    
            return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
          }
        });
    </script> 
  3. 安装 markdown-it-highlightjs 和 highlight.js:

    bash 复制代码
    npm install markdown-it-highlightjs highlight.js
  4. 引入 highlight.js 样式:

    javascript 复制代码
    import 'highlight.js/styles/default.css'; // 你可以选择其他样式
  5. 配置 markdown-it 使用 highlight.js:

    javascript 复制代码
    const md = markdownit({
      highlight: function (str, lang) {
        if (lang && hljs.getLanguage(lang)) {
          try {
            return '<pre class="hljs"><code>' +
                   hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
                   '</code></pre>';
          } catch (__) {}
        }
    
        return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
      }
    });
  6. 添加 highlight.js 样式:

    scss 复制代码
    .markdown-body .hljs {
      background: #f4f4f4;
      border-radius: 5px;
      padding: 10px;
      overflow-x: auto;
    }
    
    .markdown-body .hljs code {
      background: none;
      padding: 0;
    }

效果展示

相关推荐
oicola3 小时前
Ant Design v5 vs Tailwind CSS:组件库与样式框架的终极对决
前端·css
溪语流沙3 小时前
【Web全栈进阶】Vue Router + Pinia:SPA路由与全局状态
前端·javascript·vue.js
ManageEngineITSM3 小时前
工单优先级怎么定?影响×紧急度矩阵的设计与落地方法
java·大数据·运维·前端·数据库·变更管理
智商网输送线配件3 小时前
电子制造零散耗材补货实战:小批量混批采购平台怎么选才不停机?
大数据·服务器·前端·数据库·自动化
梦帮科技3 小时前
Web 漏洞攻防深度:WAF 规则逃逸技术(畸形分块传输、双重编码)与对抗加固
linux·前端·网络安全·ssl·web
兰亭妙微UI设计公司3 小时前
兰亭妙微软件界面设计公司的解锁按钮设计10大密码
开发语言·前端·javascript
迪幻4 小时前
封装自己的 npm 依赖并存储到个人 GitHub
前端·npm·github
u0111026754 小时前
WebP 转成 PNG 后为什么更大?图片格式转换不等于压缩
前端·javascript·vue.js
万少4 小时前
Qoder sonus模型 20分钟,复刻 马斯克 飞天汽车
前端·后端·算法
seconp4 小时前
基于Spring Boot和Vue 3的智慧旅游网站:住宿预订、行程规划与千问接入
vue.js·spring boot·毕业设计·软件工程·课程设计·旅游·毕设