安装支持vue3版本的v-md-editor插件
# 使用 npm
npm i @kangc/v-md-editor@next -S
# 使用yarn
yarn add @kangc/v-md-editor@next
在vue3项目中引入
import { creatApp } from 'vue';
import VueMarkdownEditor from '@kangc/v-md-editor';
import '@kangc/v-md-editor/lib/style/base-editor.css';
import vuepressTheme from '@kangc/v-md-editor/lib/theme/vuepress.js';
import '@kangc/v-md-editor/lib/theme/style/vuepress.css';
VueMarkdownEditor.use(vuepressTheme);
const app = creatApp(/*...*/);
app.use(VueMarkdownEditor);
在组件中使用
<template>
<v-md-editor v-model="text" height="400px"></v-md-editor>
</template>
<script>
export default {
data() {
return {
text: '',
};
},
};
</script>
使用导航
onMounted(()=>{
axios.all([requestArticleDetail(),requestComment()])
.then(axios.spread((articleRes,commentListRes)=>{
data.value=articleRes.data.res[0];
content.value=articleRes.data.res[0].articleContent;
commentList.value=commentListRes.data.res;
}))
.then(()=>{
//注意要在请求完成之后才能去获取dom节点,因为dom节点的生成依赖于请求的数据
const anchors = document.querySelectorAll('.v-md-editor-preview h1,h2,h3,h4,h5,h6');
// anchors.forEach(item=>{
// console.log(item.offsetTop);
// })
titles.value = Array.from(anchors).filter((title) => !!title.innerText.trim());
const hTags = Array.from(new Set(titles.value.map((title) => title.tagName))).sort();
titles.value = titles.value.map((el) => ({
title: el.innerText,
lineIndex: el.getAttribute('data-v-md-line'),
indent: hTags.indexOf(el.tagName),
}));
})
})
导航点击事件
const handleAnchorClick=(anchor)=>{
const navItem=document.querySelector('.v-md-editor-preview');
const { lineIndex } = anchor;
const heading = navItem.querySelector(
`.v-md-editor-preview [data-v-md-line="${lineIndex}"]`);
const top=heading.offsetTop
let timer=setInterval(()=>{
if(document.documentElement.scrollTop<top)
{
document.documentElement.scrollTop += 60
if(document.documentElement.scrollTop>=top)
clearInterval(timer)
}
else
{
document.documentElement.scrollTop -= 60
if(document.documentElement.scrollTop<=top)
clearInterval(timer)
}
},20)
}