vue加载markdown文档并生成目录

  1. 安装依赖
yarn add markdown-it
yarn add markdown-it-toc
  1. 读取markdown文件
<div
  id="content"
   v-html="md"
   style='height:900px;overflow:scroll;font-size: 16px;margin:0 20px;'
 ></div>
    
axios.get("manual.md").then(res => {
  const mds = new MarkdownIt()
  mds.use(MarkdownItDoc)
  const result = mds.render(res.data)
  this.toc = mds.toc
  this.md = result
  const _this = this
  this.$nextTick(() => {
    _this.catalogTree()
  })
});
  1. 生成目录树
catalogTree () {
      const content = document.getElementById('content').children
      var arr = []
      let currentHightestLevel
      let parentId
      let index = 0
      for (let i = 0; i < content.length; i++) {
        let header = content[i].localName
        if (/\b[h][0-9]\b/.test(header)) {
          const ele = $(content[i])
          let name = ele.text()
          let id = ele.children('a').attr('id')
          if (index === 0 || header <= currentHightestLevel) {
            currentHightestLevel = header
            parentId = id
          }
          arr.push({ id: id, label: name, parentId: parentId == id ? '0' : parentId })
          index++
        }
      }
      const tree = []
      arr.forEach(item => {
        if (item.parentId === '0') {
          tree.push(this.convertArrayToTree(arr, item))
        }
      })
      this.tree = tree
    },
    convertArrayToTree (arr, node) {
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].parentId === node.id) {
          const res = this.convertArrayToTree(arr, arr[i])
          if (node.children) {
            node.children.push(res)
          } else {
            node.children = [res]
          }
        }
      }
      return node
    }
  1. 点击目录跳转至指定位置
handleNodeClick (data) {
      document.querySelector('#' + data.id).scrollIntoView(true)
    }
  1. 目录设置可拖拽
 <div
      id="tree"
      style="position:fixed; right:10px;top:10px;width:200px;z-index:99"
      v-drag
    >
      <el-tree
        :data="tree"
        :default-expand-all="true"
        @node-click="handleNodeClick"
      ></el-tree>
    </div>
    
    Vue.directive('drag', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    el.onmousedown = function (e) {
      var disx = e.pageX - el.offsetLeft //获取鼠标相对元素距离
      var disy = e.pageY - el.offsetTop

      document.onmousemove = function (e) {
        //鼠标移动触发事件,元素移到对应为位置
        el.style.left = e.pageX - disx + 'px'
        el.style.top = e.pageY - disy + 'px'
      }
      document.onmouseup = function () {
        //鼠标抬起,清除绑定的事件,元素放置在对应的位置
        document.onmousemove = null
        document.onmousedown = null
      }
      e.preventDefault() //阻止浏览器的默认事件
    }
  }
})
  1. 样式调整
h3 {
  margin: 10px 0;
}
p {
  margin-block-start: 1em;
  margin-block-end: 1em;
}

pre {
  background-color: #f5f7f9;
  padding: 20px;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值