使用vue-markdown实现markdown文件预览
Vue-Markdown 是一个轻量级且高效的库,用于在Vue.js应用程序中渲染Markdown文本。它允许开发者以简洁的方式将Markdown的强大功能与Vue组件的灵活性相结合,提升开发效率和用户体验。vue-markdown 是一个基于 marked.js 的 Vue Markdown 插件。它是一个简单易用的 Markdown 解析器,可以方便地将 Markdown 文档解析为 HTML。它有如下特点:
功能强大:支持 Markdown 语法的全部特性,例如标题、列表、链接等。
易于使用:只需要在 Vue 组件中引入 vue-markdown 插件,并使用简单的模板语法即可实现 Markdown 的解析和渲染。
高性能:基于 marked.js,性能优异,可以快速地解析和渲染大量的 Markdown 文档。
扩展性强:支持自定义渲染规则,可以通过插件扩展功能,以满足更多的需求。
一、插件使用
1、插件说明
vue-markdown插件的灵活性较好,支持直接传递Markdown字符串,或者通过绑定数据属性来动态渲染Markdown。此外,还可以自定义渲染规则,扩展或替换特定的Markdown语法,以满足个性化需求。在github上看了作者的源码,发现该插件也引入了markdown-it,并且支持大部分的markdown-it的插件,通过插件的引入即可使用。
官方demo
1)slots
在组件中使用 vue-markdown 插件,可以在模板中添加 slots、props 和 events 的代码,如下:
2)配置参数
| 参数名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| watches | Array | ["source", "show", "toc"] | 是否开启监视数据变化,自动改变HTML。 |
| source | String | null | 要转换为 HTML 的 Markdown 字符串。 |
| show | Boolean | true | 是否显示转换后的 HTML 内容。 |
| html | Boolean | true | 是否允许解析 HTML 标签。默认为 false。 |
| xhtml-out | Boolean | true | 是否输出 XHTML 格式。<br></br> => <br /> |
| breaks | Boolean | true | 是否将换行符解析为 <br/> 标签。\n => <br> |
| linkify | Boolean | true | 是否将纯文本链接转换为链接。 |
| emoji | Boolean | true | 是否支持 emoji 表情。 |
| typographer | Boolean | true | 是否开启排版选项,例如引号转换、省略号转换等。 |
| lang-prefix | String | language- | 语法高亮语言前缀。 |
| quotes | String | “”‘’ | 引用标记。中文: “”‘’, 德文:„“‚‘ ,俄罗斯: «»„“ |
| table-class | String | table | 表格的 CSS 类名。 |
| task-lists | Boolean | true | 是否支持任务列表。 |
| toc | Boolean | false | 是否生成目录。 |
| toc-id | String | undefined | 生成目录的Id |
| toc-class | String | table | 目录的 CSS 类名。 |
| toc-first-level | Number | 2 | 目录最顶层标题的级别,取值范围为 1-6。默认为 2。 |
| toc-last-level | Number | 'toc-first-level' + 1 | 目录最后一层标题的级别,取值范围为 1-6。默认为5。 |
| toc-anchor-link | Boolean | true | 在标题中启用自动锚链接 |
| toc-anchor-class | String | toc-anchor | 自定义锚类名 |
| toc-anchor-link-symbol | String | # | 目录中的锚点链接的符号。默认为 ‘#’。 |
| toc-anchor-link-space | Boolean | true | 目录中的锚点链接前的空格。 |
| toc-anchor-link-class | String | toc-anchor-link | 目录中的锚点链接的 CSS 类名。 |
| anchorAttributes | Object | {} | 锚点标签的属性。: '_blank’orrel: ‘nofollow’` |
| prerender | Function (String) String | null | 在转换 HTML 前的回调函数。 |
| postrender | Function (String) String | null | 在转换 HTML 后的回调函数。 |
3)事件
vue-markdown 插件中,提供了以下两个事件:
| 方法名称 | 参数 | 描述 |
|---|---|---|
| rendered | 显示的html元素(string) | 渲染结束后触发 |
| toc-rendered | 目录html元素(string) | TOC目录渲染结束后触发,如果toc传的是false则不会触发 |
2、安装
3、使用
二、页面中渲染并添加目录
在实际的项目开发过程中,为了方便定位与查阅,需要目录大纲,我们可以在旁边加上一个目录大纲,这里使用的el-tree进行目录的展示。
1、HTML部分
<template> <div class="page-api" id="myElement"> <vue-markdown id="content" class="api-content" :source="markdownContent"></vue-markdown> <div class="api-tree" id="tree"> <el-tree :data="tree" :default-expand-all="true" @node-click="handleNodeClick"></el-tree> </div> </div> </template>
2、JS部分
import VueMarkdown from 'vue-markdown';
import markdownItAnchor from 'markdown-it-anchor';
import markdownItToc from 'markdown-it-table-of-contents';
import markdownItEmoji from 'markdown-it-emoji';
import markdownItKatex from 'markdown-it-katex';
export default {
data() {
return {
markdown: '# h1 Heading\n ## h2 Heading\n ### h3 Heading',
markdownContent: '',
tree: [],
plugins: [markdownItAnchor, [markdownItToc, { includeLevel: [2, 3] }], markdownItEmoji, markdownItKatex]
};
},
mounted() {
this.loadMarkdownFile();
},
components: {
VueMarkdown
},
methods: {
async loadMarkdownFile() {
try {
//引入在public文件夹下的md文件
const response = await fetch('/XXXX.md');
const markdownText = await response.text();
this.markdownContent = markdownText;
this.$nextTick(() => {
this.catalogTree();
});
} catch (error) {
console.error('Failed to load the Markdown file:', error);
}
},
catalogTree() {
const content = document.getElementById('content').children;
var arr = [];
let currentHightestLevel;
let parentId;
let index = 0;
let nodeArr = [];
let tree = [];
for (let i = 0; i < content.length; i++) {
let header = content[i].localName;
//如果是标题进行下一步
if (/\b[h][0-9]\b/.test(header)) {
let ele = content[i]; // 直接使用DOM元素
let name = ele.textContent; // 获取元素的文本内容
ele.setAttribute('id', i); // 设置元素的ID
let id = i;
if (index === 0 || header <= currentHightestLevel) {
currentHightestLevel = header;
parentId = id;
}
arr.push({
id: id,
label: name,
parentId: parentId == id ? '0' : parentId
});
index++;
}
}
arr.forEach((item) => {
if (item.parentId === '0') {
tree.push(this.convertArrayToTree(arr, item));
}
});
this.tree = tree;
},
convertArrayToTree(arr, node) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].parentId === node.id) {
const res = this.convertArrayToTree(arr, arr[i]);
if (node.children) {
node.children.push(res);
} else {
node.children = [res];
}
}
}
return node;
},
handleNodeClick(data) {
let anchorElement = document.getElementById(data.id);
let scrollPosition = anchorElement.offsetTop - 20;
let myElement = document.getElementById('myElement');
myElement.scrollTo({
left: 0,
top: scrollPosition,
behavior: 'smooth'
});
}
}
};3、CSS样式
.page-api {
display: flex;
width: 100%;
height: 100%;
overflow-y: scroll;
background-color: #fff;
}
.api-tree {
position: fixed;
right: 20px;
top: 120px;
width: 250px;
height: 600px;
margin-right: 10px;
overflow-y: scroll;
/* text-overflow: ellipsis; */
z-index: 99;
.el-tree {
background: none;
color: #686868;
.el-tree-node:focus > .el-tree-node__content,
.el-tree-node__content:hover {
background: none;
color: rgb(24, 144, 255);
}
}
}
.api-tree::-webkit-scrollbar {
width: 8px;
}
.api-content {
flex: 1;
width: 80%;
margin-left: 20px;
margin-right: 220px;
padding: 0 30px;
h2 {
margin-left: 20px;
margin-bottom: 10px;
}
h3 {
margin-left: 25px;
margin-bottom: 8px;
}
h4 {
margin-left: 30px;
margin-bottom: 5px;
}
li {
margin-left: 40px;
}
code {
border-radius: 2px;
color: #ffaa7f;
margin: 0 2px;
padding: 3px 5px;
white-space: pre-wrap;
}
table {
border-collapse: collapse;
border-spacing: 0;
th,
td {
border: 1px solid #ddd;
padding: 6px 13px;
margin: 0;
}
}
pre {
background: rgba(0, 0, 0, 0.7);
padding: 20px 30px;
}
}
.page-api::-webkit-scrollbar {
width: 8px;
}
/* 滚动条滑块样式 */
.page-api::-webkit-scrollbar-thumb {
background-color: #888; /* 设置滑块背景颜色 */
border-radius: 4px; /* 设置滑块圆角 */
}4、效果展示
上一篇:Vue3利用vue-plugin-hiprint插件实现无预览打印功能
栏 目:JavaScript
本文标题:使用vue-markdown实现markdown文件预览
本文地址:https://zz.feitang.co/wangluobiancheng/23703.html
您可能感兴趣的文章
- 07-25如何使用 Deepseek 写的uniapp油耗计算器
- 07-25JavaScript其他类型的值转换为布尔值的规则详解
- 07-25JavaScript实现给浮点数添加千分位逗号的多种方法
- 07-25ReactNative环境搭建的教程
- 07-25JavaScript获取和操作时间戳的用法详解
- 07-25通过Vue实现Excel文件的上传和预览功能
- 07-25Node使用Puppeteer监听并打印网页的接口请求
- 07-25在Node.js中设置响应的MIME类型的代码详解
- 07-25Vue3解决Mockjs引入后并访问404(Not Found) 的页面报错问题
- 07-25如何利用SpringBoot与Vue3构建前后端分离项目


阅读排行
推荐教程
- 04-23JavaScript Array实例方法flat的实现
- 04-23Vue3使用v-if指令进行条件渲染的实例代码
- 04-23THREE.JS使用TransformControls对模型拖拽的代码实例
- 07-21JavaScript判断数据类型的四种方式总结
- 07-22JavaScript随机数生成各种技巧及实例代码
- 07-21JavaScript检查变量类型的常用方法
- 07-21基于vue3与supabase系统认证机制详解
- 04-23vue3+ts项目搭建的实现示例
- 07-21JavaScript双问号操作符(??)的惊人用法总结大全
- 07-22使用Node.js实现GitHub登录功能






