vue2_markdown的内容目录生成
        【摘要】 @[TOC] ⭐前言大家好!我是yma16,本文分享在vue2的markdown文本内容渲染和目录生成背景:优化个人博客功能,解决markdown文档的目录视图问题 ⭐引入vue-markdownvue-mardkown渲染依赖$ npm install vue-mardkown 💖 全局配置import VueMarkdown from 'vue-markdown'new Vue({  ...
    
    
    
    @[TOC]
⭐前言
大家好!我是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的目录生成到此结束!
 💖 感谢你的阅读 💖
 如有不足或者错误欢迎指出!
 
            【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
                cloudbbs@huaweicloud.com
                
            
        
        
        
        
        
        
        - 点赞
 - 收藏
 - 关注作者
 
            
           
评论(0)