文章目录
- ⭐前言
- ⭐引入vue-markdown
- 💖 全局配置
- 💖 渲染选项
- 💖 取出markdown的标题层级
- ⭐结束
⭐前言
大家好!我是yma16,本文分享在vue2的markdown文本内容渲染和目录生成
背景:
优化个人博客功能,解决markdown文档的目录视图问题
⭐引入vue-markdown
vue-mardkown渲染依赖
$ npm install vue-mardkown
💖 全局配置
import VueMarkdown from 'vue-markdown'
new Vue({
components: {
VueMarkdown
}
})
💖 渲染选项
vue-markdown提供的参数详情
Prop | Type | Default | Describe |
---|---|---|---|
watches | Array | ["source", "show", "toc"] | HTML refresh automatically when the prop in this array changed |
source | String | null | the markdown source code |
show | Boolean | true | enable render to the default slot automatically |
html | Boolean | true | enable HTML syntax in source |
xhtml-out | Boolean | true | <br></br> => <br /> |
breaks | Boolean | true | \n => <br> |
linkify | Boolean | true | autoconvert URL-like text to link |
emoji | Boolean | true | :) => 😃 |
typographer | Boolean | true | enable some language-neutral replacement and quotes beautification |
lang-prefix | String | language- | CSS language prefix for fenced blocks |
quotes | String | “”‘’ | use “”‘’ for Chinese, „“‚‘ for German, «»„“ for Russian |
table-class | String | table | customize html class of the <table> |
task-lists | Boolean | true | enable GFM task list |
toc | Boolean | false | enable automatic table of contents |
toc-id | String | undefined | the HTML id to render TOC |
toc-class | String | table | customize html class of the <ul> wrapping the TOC |
toc-first-level | Number | 2 | use 2 if you want to skip <h1> from the TOC |
toc-last-level | Number | 'toc-first-level' + 1 | use 5 if you want to skip <h6> from the TOC |
toc-anchor-link | Boolean | true | enable the automatic anchor link in the headings |
toc-anchor-class | String | toc-anchor | customize the anchor class name |
toc-anchor-link-symbol | String | # | customize the anchor link symbol |
toc-anchor-link-space | Boolean | true | enable inserting a space between the anchor link and heading |
toc-anchor-link-class | String | toc-anchor-link | customize the anchor link symbol class name |
anchorAttributes | Object | {} | anchor tag attributes such as target: '_blank' or rel: 'nofollow' |
prerender | Function (String) String | null | filter function before markdown parse |
postrender | Function (String) String | null | filter function after markdown parse |
组件配置: |
<template>
<div style="width: 100%">
<MarkDirTree :dirContent="dirContent"/>
<VueMarkdown
:source="content"
:toc="true"
v-highlight
style="width: 100%; text-align: left"
></VueMarkdown>
</div>
</template>
<script>
import MarkDirTree from './MarkDirTree'
export default {
components: {MarkDirTree},
name: 'DesignMarkdown',
props: {
contentSource: undefined
},
data () {
return {
content: '',
dirContent: []
}
},
watch: {
contentSource: {
handler (newVal) {
this.content = newVal || ''
this.getDirContent(newVal)
},
deep: true,
immediate: true
}
},
mounted () {
console.log('design vuemarkdown')
},
methods: {
// 树状目录获取
getDirContent (mdContent) {
if (!mdContent) {
return []
}
const lineT = mdContent.split('\n')
const titleArray = lineT.filter(item => item && item[0] === '#')
console.log('titleArray', titleArray)
const dirArray = titleArray.map(item => {
return item.replace(/\r/g, '')
})
console.log('dirArray', dirArray)
const dirLevelArray = dirArray.map(item => {
let level = 0
for (let loc in item) {
if (item[loc] === '#') {
++level
}
}
const itemBack = item
const value = itemBack.replace(/#/g, '').trim()
return {
level,
value
}
})
console.log('dirLevelArray', dirLevelArray)
this.dirContent = dirLevelArray
}
}
}
</script>
渲染样式效果如下:
注意:
toc是markdown渲染的id显示
渲染内容如下图:
💖 取出markdown的标题层级
字符串处理识别#
标记层级,拿出数据内容
应为markdown本身有序,所以无需排序
渲染目录逻辑
- 根据层级渲染缩进
- 渲染标题内容
- 标题加上锚点跳转事件
渲染目录代码如下:
<template>
<div class="markdown-link">
<div v-for="(item,index) in content" :key="index">
<div>
<template v-for="levelItem in item.level">
</template>
<span @click="jumpText(item)" class="link-title">{{item.value}}</span>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
dirContent: undefined
},
data () {
return {
content: ''
}
},
watch: {
dirContent: {
handler (newVal) {
console.log('newVal', newVal)
this.content = newVal || ''
},
deep: true,
immediate: true
}
},
mounted () {
console.log('design vuemarkdown dir')
},
methods: {
jumpText (item) {
const {level, value} = item
console.log(level, value)
this.herfTo(value)
},
herfTo (id) {
const returnEle = document.querySelector('#' + id) // 获取跳转去的节点
if (returnEle) {
returnEle.scrollIntoView(true) // 让当前的元素滚动到浏览器窗口的可视区域内(true:对象的顶端与当前窗口的顶部对齐,false:对象的底端与当前窗口的底部对齐)
}
}
}
}
</script>
<style>
.markdown-link{
position: fixed;
background:rgba(64, 158, 255,.5);
float: right;
max-width: 400px;
padding:20px;
right:120px;
top:100px;
border-radius: 20px;
box-shadow: 0 5px 20px rgba(0,0,0,0.4);
transition: 2s;
}
.markdown-link:hover{
background: rgba(64, 158, 255,.9);
}
.link-title{
cursor: pointer;
color: #ffffff;
}
.link-title:hover{
color: #ff995e;
}
</style>
效果如下:
⭐结束
本文markdown的目录生成到此结束!
💖 感谢你的阅读 💖
如有不足或者错误欢迎指出!