zoukankan      html  css  js  c++  java
  • vue-markdown 之 markdown-it, 以及 table of content 的实现:markdown-it-toc-and-anchor

    1. npm install --save uslug markdown-it markdown-it-toc-and-anchor

    2. 主要代码

    • <template>
        <div id="lab_exp_book">
      
              ... ...
      
                <div class="directory_box">
                  <div class="directory_title">目录</div>
                  <ul class="directory_ul">
                    <li v-for="(item, index) in tocShow" :key="index">
                      <div v-if="item.children.length===0">
                        <a :class="{active: curContentScrollTop===item.anchorY}" class="lab_section_class hover_change_color"
                           @click="handleDirClick(item)" href="javascript:">{{item.nodeName}}</a>
                      </div>
      
                      <div v-else>
                        <div :class="{active: curContentScrollTop===item.anchorY || (!item.anchorY && index === 0)}" class="lab_section_title hover_change_color"
                             @click="handleDirClick(item)">{{item.nodeName}}</div>
                        <ul class="lab_section_children">
                          <li v-for="(each, index) in item.children" :key="index">
                            <div v-if="each.children.length===0">
                              <a  :class="{active: curContentScrollTop===each.anchorY}" class="lab_section_class hover_change_color"
                                  @click="handleDirClick(each)" href="javascript:">{{each.nodeName}}</a>
                            </div>
      
                            <div v-else>
                              <div :class="{active: curContentScrollTop===each.anchorY}" class="lab_section_title hover_change_color"
                                   @click="handleDirClick(each)">{{each.nodeName}}</div>
                              <ul class="lab_section_children">
                                <li v-for="(third, index) in each.children" :key="index">
                                  <div>
                                    <a  :class="{active: curContentScrollTop===third.anchorY}" class="lab_section_class hover_change_color"
                                        @click="handleDirClick(third)" href="javascript:">{{third.nodeName}}</a>
                                  </div>
                                </li>
                              </ul>
                            </div>
                          </li>
                        </ul>
                      </div>
                    </li>
                  </ul>
      
                  <div class="directory_tips">开始学习后可阅读实验手册内容</div>
                </div>
              </div>
      
              <div class="right_book_content" ref="rightBookContent">
                <div class="book_box" v-if="1">
                  <div class="lab_simple_content clearfix" v-html="htmlStr">
                  </div>
                </div>
      
              ... ...
      
        </div>
      </template>
      
      <script>
        import uslug from 'uslug'
        import MarkdownIt from 'markdown-it'
        import markdownItTocAndAnchor from 'markdown-it-toc-and-anchor'
        data () {
            return {
               mdStr: '相关md字符串',
               htmlStr: '',    // 渲染到页面
               tocArray: [],
               tocShow: [],    // 渲染到页面
               isFirstClickDir: true,
               curContentScrollTop: 2
            }
        },
          computed: {
            ...mapState({
              labDirectory: state => state.lab.labDirectory
            })
          },
          watch: {
            tocArray: {
              deep: true,
              handler (newValue) {
                const oldArr = JSON.parse(JSON.stringify(newValue))
      
                let tocArr = []
                let cur1Arr = null
                let cur2Arr = null
                let cur3Arr = null
                let cur4Arr = null
                let cur5Arr = null
                oldArr.reduce((newArr, next) => {
                  if (next.level === 2) {
                    cur1Arr = JSON.parse(JSON.stringify(next))
                    cur1Arr.children = []
                    cur1Arr.nodeName = cur1Arr.content
                    cur2Arr = cur1Arr.children
                    tocArr.push(cur1Arr)
                  } else if (next.level === 3) {
                    cur3Arr = JSON.parse(JSON.stringify(next))
                    cur3Arr.children = []
                    cur3Arr.nodeName = cur3Arr.content
                    cur4Arr = cur3Arr.children
                    cur2Arr.push(cur3Arr)
                  } else if (next.level === 4) {
                    cur5Arr = JSON.parse(JSON.stringify(next))
                    cur5Arr.children = []
                    cur5Arr.nodeName = cur5Arr.content
                    // cur6Arr = cur5Arr.children
                    cur4Arr.push(cur5Arr)
                  }
                  return newArr
                }, [])
      
                this.tocShow = tocArr
              }
            }
          },
          async mounted () {
            this.myConsole('_labExpBookInit')
            this._initLabExpBook()
            await this.$store.dispatch('getLabDirectory')
          },
          methods: {
            _uslugify(x) {
              return uslug(x)
            },
            _initLabExpBook () {
              let md = new MarkdownIt({
                html: false,
                xhtmlOut: true,
                typographer: true
              })
      
              md.use(markdownItTocAndAnchor, {slugify: this._uslugify})
      
              this.htmlStr = md.set({
                tocCallback: (tocMarkdown, tocArray, tocHtml) => {
                  this.tocArray = tocArray
                }
              }).render(this.mdStr)
            },
            handleDirClick(dirNode) {
              window.scrollTo(0, 502)
              if (this.isFirstClickDir) {
                this.isFirstClickDir = false
                this._initDirScrollPos()
                bindEventFunc(this.$refs.rightBookContent, 'scroll', () => {
                  this.curContentScrollTop = this.$refs.rightBookContent.scrollTop
                })
              }
              this.$refs.rightBookContent.scrollTo({ top: dirNode.anchorY, left: 0, behavior: 'smooth' })
            },
            _initDirScrollPos () {
              this.tocShow = this.tocShow.map((ele) => {
                myConsole(ele.anchor)
                this._addAnchorY(ele)
                if (ele.children.length > 0) {
                  ele.children.forEach((each, i) => {
                    myConsole(ele.children[i].anchor)
                    this._addAnchorY(ele.children[i])
                    if (each.children.length > 0) {
                      each.children.forEach((one, j) => {
                        myConsole(ele.children[i].children[j].anchor)
                        this._addAnchorY(ele.children[i].children[j])
                      })
                    }
                  })
                }
                return ele
              })
            },
            _addAnchorY (ele) {
              ele.anchorY = document.getElementById(ele.anchor).getBoundingClientRect().top - 120
            }
          ... ...
      </script>

    3. 效果截图

    --------小尾巴 ________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...
  • 相关阅读:
    邱洁红(帮别人名字作诗)
    为了你,我已等了一千年
    为什么才华横溢的人总是怀才不遇
    这三种力量,让你的人生从此大不一样……
    赠中华儿女
    管理的7重境界
    写下你人生101个不可思议的目标
    忙碌啊,请别带走我的诗魂
    宋彦澍(帮别人名字作诗)
    慈善家洛克菲勒先生的思想精华 自信与坚持
  • 原文地址:https://www.cnblogs.com/tianxiaxuange/p/10908230.html
Copyright © 2011-2022 走看看