vue2_markdown的内容目录生成

⭐前言

大家好!我是yma16,本文分享在vue2的markdown文本内容渲染和目录生成
背景:
优化个人博客功能,解决markdown文档的目录视图问题

⭐引入vue-markdown

vue-mardkown渲染依赖

$ npm install vue-mardkown

💖 全局配置

import VueMarkdown from 'vue-markdown'

new Vue({
  components: {
    VueMarkdown
  }
})

💖 渲染选项

vue-markdown提供的参数详情

PropTypeDefaultDescribe
watchesArray["source", "show", "toc"]HTML refresh automatically when the prop in this array changed
sourceStringnullthe markdown source code
showBooleantrueenable render to the default slot automatically
htmlBooleantrueenable HTML syntax in source
xhtml-outBooleantrue<br></br> => <br />
breaksBooleantrue\n => <br>
linkifyBooleantrueautoconvert URL-like text to link
emojiBooleantrue:) => 😃
typographerBooleantrueenable some language-neutral replacement and quotes beautification
lang-prefixStringlanguage-CSS language prefix for fenced blocks
quotesString“”‘’use “”‘’ for Chinese, „“‚‘ for German, «»„“ for Russian
table-classStringtablecustomize html class of the <table>
task-listsBooleantrueenable GFM task list
tocBooleanfalseenable automatic table of contents
toc-idStringundefinedthe HTML id to render TOC
toc-classStringtablecustomize html class of the <ul> wrapping the TOC
toc-first-levelNumber2use 2 if you want to skip <h1> from the TOC
toc-last-levelNumber'toc-first-level' + 1use 5 if you want to skip <h6> from the TOC
toc-anchor-linkBooleantrueenable the automatic anchor link in the headings
toc-anchor-classStringtoc-anchorcustomize the anchor class name
toc-anchor-link-symbolString#customize the anchor link symbol
toc-anchor-link-spaceBooleantrueenable inserting a space between the anchor link and heading
toc-anchor-link-classStringtoc-anchor-linkcustomize the anchor link symbol class name
anchorAttributesObject{}anchor tag attributes such as target: '_blank' or rel: 'nofollow'
prerenderFunction (String) Stringnullfilter function before markdown parse
postrenderFunction (String) Stringnullfilter 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>

渲染样式效果如下:

markdown-render

注意:
toc是markdown渲染的id显示
渲染内容如下图:
title-toc-render

💖 取出markdown的标题层级

字符串处理识别#标记层级,拿出数据内容
应为markdown本身有序,所以无需排序
渲染目录逻辑

  1. 根据层级渲染缩进
  2. 渲染标题内容
  3. 标题加上锚点跳转事件

渲染目录代码如下:

<template>
  <div class="markdown-link">
    <div v-for="(item,index) in content" :key="index">
      <div>
        <template v-for="levelItem in item.level">
          &nbsp;
        </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>

效果如下:
title-link

⭐结束

本文markdown的目录生成到此结束!
💖 感谢你的阅读 💖
如有不足或者错误欢迎指出!
scene-gril

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 28
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yma16

感谢支持!共勉!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值