Vue根据富文本内容生成目录

页面内容根据v-html渲染,读取标签并生成目录树,最终使用el-tree展示

 首先贴一个生成树结构的代码,网上Copy得来

toTree(data){
    // 删除 所有 children,以防止多次调用
    data.forEach(function (item) {
      delete item.children;
    });

    // 将数据存储为 以 id 为 KEY 的 map 索引数据列
    var map = {};
    data.forEach(function (item) {
      map[item.id] = item;
    });
    var val = [];
    data.forEach(function (item) {
      // 以当前遍历项的pid,去map对象中找到索引的id
      var parent = map[item.p_id];
      // 好绕啊,如果找到索引,那么说明此项不在顶级当中,那么需要把此项添加到,他对应的父级中
      if (parent) {
        (parent.children || (parent.children = [])).push(item);
      } else {
        //如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中,作为顶级
        val.push(item);
      }
    });
    return val;
  }

然后封装生成Dom树的方法

/**
     * 生成目录
     * */
    makeToc(){
      if(process.client){
        this.$nextTick(() => {
          // 定义参与目录生成的标签
          const tocTags = ["H1","H2","H3","H4","H5","H6"];

          // 目录树结果
          const tocArr = [];

          // 获取所有标题标签
          const headDoms = Array.from(this.$refs.aContent.childNodes).filter(item => tocTags.includes(item.tagName));

          // 遍历标题标签
          headDoms.forEach((item,index,arr) => {
            // 给标题添加id
            item.id = `h-${index + 1}`;
            // 获取当前节点前面的节点
            let prevs = arr.filter((i,j) => j < index);
            // 过滤前面的节点为合理节点
            // 如 h3节点前  只能为 h1 h2 h3
            prevs = prevs.filter(i => tocTags.filter((i,j) => j <= tocTags.findIndex(i => i == item.tagName)).includes(i.tagName));
            // 对前面的节点进行排序,距离自身节点近的排在前面
            // 如 div > p > span > img  当前为img
            // 常规获取节点为 [div,p,span,img]
            // 排序后获取节点为 [img,span,p,div]
            prevs = prevs.sort((a,b) => -(a.id.replace('h-','')) - b.id.replace('h-',''));
            // 查询距离自身节点最近的不同于当前标签的节点
            const prev = prevs.find(i => i.tagName != item.tagName);

            tocArr.push({
              id:index + 1,// 抛出id
              tag:item.tagName,// 抛出标签名称
              label:item.innerText,// 抛出标题
              p_id:item.tagName == "H1" ? 0 : Number(prev.id.replace("h-",'')),// 抛出父级id
            })
          })

          // 使用上述方法生成树 最后在el-tree的data中使用 tocData即可
          this.tocData = this.toTree(tocArr);
        })
      }
    },

toTree方法基本不用改,makeToc方法少量改动即可! 

 嘿,愿你代码永无bug,人生永无坎坷!

嘿,愿你代码永无bug,人生永无坎坷!

嘿,愿你代码永无bug,人生永无坎坷!

嘿,愿你代码永无bug,人生永无坎坷!

嘿,愿你代码永无bug,人生永无坎坷!

嘿,愿你代码永无bug,人生永无坎坷!

猜你喜欢

转载自blog.csdn.net/qq_41980461/article/details/125278020