1. 安装依赖库
npm install @kangc/v-md-editor
npm install highlight.js@^10.7.3 markdown-it-anchor@^8.6.4
2. 全局配置(在 main.js
中)
// Markdown 编辑器配置
import VMdEditor from '@kangc/v-md-editor'
import githubTheme from '@kangc/v-md-editor/lib/theme/github'
import '@kangc/v-md-editor/lib/theme/style/github.css'
import hljs from 'highlight.js/lib/core'
import markdownItAnchor from 'markdown-it-anchor'
// 配置 Markdown 解析器
VMdEditor.use(githubTheme, {
Hljs: hljs,
extend(md) {
md.use(markdownItAnchor, {
slugify: (s) => s.toLowerCase().replace(/[^\w\u4e00-\u9fa5]+/g, '-')
});
},
});
// 注册到 Vue
Vue.use(VMdEditor);
3. 创建Markdown渲染组件
在 components
目录下新建 MarkdownViewer.vue
:
<template>
<div class="markdown-wrapper">
<!-- 左侧目录 -->
<div class="toc" v-if="toc.length">
<div class="toc-title">目录导航</div>
<div
v-for="(item, index) in toc"
:key="index"
:class="['toc-item', `toc-level-${item.level}`]"
>
<a @click="scrollToAnchor(item.anchor)">{{ item.title }}</a>
</div>
</div>
<!-- 右侧内容 -->
<div class="content">
<v-md-editor
:value="content"
mode="preview"
left-toolbar="undefined"
@toc-change="handleTocChange"
/>
</div>
</div>
</template>
<script>
export default {
props: {
content: {
type: String,
required: true
}
},
data() {
return {
toc: []
};
},
methods: {
handleTocChange(toc) {
this.toc = toc;
},
scrollToAnchor(anchor) {
const target = document.querySelector(`#${anchor}`);
if (target) {
target.scrollIntoView({ behavior: 'smooth' });
}
}
}
};
</script>
<style scoped>
.markdown-wrapper {
display: flex;
min-height: calc(100vh - 120px);
}
.toc {
width: 240px;
padding: 15px;
border-right: 1px solid #eaecef;
position: sticky;
top: 60px;
max-height: 90vh;
overflow-y: auto;
}
.toc-title {
font-weight: 600;
margin-bottom: 10px;
color: #2c3e50;
}
.toc-item {
line-height: 1.5;
padding: 4px 0;
}
.toc-level-2 { margin-left: 0 }
.toc-level-3 { margin-left: 15px }
.toc-level-4 { margin-left: 30px }
.toc-level-5 { margin-left: 45px }
.content {
flex: 1;
padding: 20px 40px;
max-width: 900px;
}
/* 覆盖默认样式 */
.v-md-editor >>> pre {
background-color: #f6f8fa !important;
padding: 16px !important;
border-radius: 6px;
}
.v-md-editor >>> table {
border-collapse: collapse;
margin: 1em 0;
}
.v-md-editor >>> table td,
.v-md-editor >>> table th {
border: 1px solid #dfe2e5;
padding: 0.6em 1em;
}
</style>
4.假设文件存放在 public/docs 目录
5. 在页面中使用组件,并添加回到顶部按钮
<template>
<div>
<markdown-viewer :content="mdContent" />
<button v-show="showBackToTop" class="back-to-top" @click="scrollToTop">回到顶部</button>
</div>
</template>
<script>
import MarkdownViewer from '@/components/MarkdownViewer';
export default {
components: { MarkdownViewer },
data() {
return {
mdContent: '',
showBackToTop: false,// 控制回到顶部按钮的显示与隐藏
};
},
mounted() {
// 假设文件存放在 public/docs 目录
fetch('/docs/work.md')
.then(res => res.text())
.then(text => {
this.mdContent = text;
});
// 监听页面滚动事件
window.addEventListener("scroll", this.handleScroll);
},
beforeDestroy() {
// 组件销毁前移除滚动监听事件,避免内存泄漏
window.removeEventListener("scroll", this.handleScroll);
},
methods: {
handleScroll() {
// 当页面滚动距离超过 300px 时,显示回到顶部按钮
this.showBackToTop = window.scrollY > 300;
},
scrollToTop() {
// 平滑滚动到页面顶部
window.scrollTo({
top: 0,
behavior: "smooth",
});
},
},
};
</script>
<style scoped>
.back-to-top {
position: fixed;
bottom: 20px;
right: 20px;
padding: 10px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
z-index: 100;
}
.back-to-top:hover {
background-color: #0056b3;
}
</style>
五、图片路径处理技巧
-
本地图片(推荐存放在
public/md-images
):
-
网络图片直接使用 URL:
