文章目录
-
- ⭐前言
- ⭐引入vue-markdown
-
- [💖 全局配置](#💖 全局配置 "#x1F496__10")
- [💖 渲染选项](#💖 渲染选项 "#x1F496__20")
- [💖 取出markdown的标题层级](#💖 取出markdown的标题层级 "#x1F496_markdown_135")
- ⭐结束
⭐前言
大家好!我是yma16,本文分享在vue2的markdown文本内容渲染和目录生成
背景:
优化个人博客功能,解决markdown文档的目录视图问题
⭐引入vue-markdown
vue-mardkown渲染依赖
javascript
$ npm install vue-mardkown
💖 全局配置
javascript
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 |
组件配置: |
javascript
<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本身有序,所以无需排序
渲染目录逻辑
- 根据层级渲染缩进
- 渲染标题内容
- 标题加上锚点跳转事件
渲染目录代码如下:
javascript
<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的目录生成到此结束!
💖 感谢你的阅读 💖
如有不足或者错误欢迎指出!