如何在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-highlightjshighlight.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;
    }

效果展示

相关推荐
迷雾漫步者2 小时前
React封装倒计时按钮
前端·react.js·前端框架
2301_795168583 小时前
javascript基础从小白到高手系列一十二:JSON
javascript·udp·json
LCG元4 小时前
Vue.js组件开发-如何实现路由懒加载
vue.js
m0_672449604 小时前
基础vue3前端登陆注册界面以及主页面设计
前端·vue.js·elementui
匹马夕阳4 小时前
Vue3中使用组合式API通过路由传值详解
前端·javascript·vue.js
zpjing~.~4 小时前
VUE中css样式scope和deep
前端·css·vue.js
fxshy4 小时前
Vue3父子组件双向绑定值用例
前端·javascript·vue.js
LCG元4 小时前
Vue.js组件开发-如何实现表头搜索
vue.js
蓝黑20205 小时前
从Vant图标的CSS文件提取图标文件
前端·css·python·vant