溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄

發(fā)布時(shí)間:2022-04-12 13:36:52 來源:億速云 閱讀:314 作者:iii 欄目:開發(fā)技術(shù)

這篇“Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄”文章吧。

前言

如下。

Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄

沒錯(cuò),遞歸組件可以解決我這個(gè)困惑,遞歸無非就是自己調(diào)用自己,我們編寫好合理的組件渲染邏輯之后,在組件內(nèi)部自己調(diào)用自己,這就是遞歸組件,接下來請(qǐng)看我的解決步驟吧!

用正則匹配出所有的h標(biāo)簽并且保存在數(shù)組中

//這里的str是用MarkdownIt解析生成的html字符串
  const menu = [...str.matchAll(/<h.*>.*</h.>/g)]

效果如下

Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄

封裝函數(shù),將數(shù)組中的內(nèi)容變成父子結(jié)構(gòu)

//我的每個(gè)菜單的類型
class menuItem {
  title: string
  children?: menuItem[]
  type: number   //type為1表示是h2標(biāo)簽
  index: number    //index表示是type對(duì)應(yīng)的第幾個(gè)h標(biāo)簽
  constructor(
    title: string,
    type: number,
    index: number,
    children: menuItem[] = []
  ) {
    this.title = title
    this.children = children
    this.type = type
    this.index = index
  }
}
export default function (menu: any[]): any[] {
  //保存所有h min標(biāo)簽
  const arr: menuItem[] = []
  const arrIndex: number[] = new Array(7).fill(0)
  // 用于保存前一個(gè)層的結(jié)點(diǎn)。例如我當(dāng)前遍歷的是type=3的item,那么我需要知道它所屬于哪個(gè)type=2的item
  // 如果有就添加到它的children中,如果沒有就添加到pre[3]中
  const pre = new Array(7).fill(null)
  //記錄h min是哪個(gè)標(biāo)簽(例如h2)
  let minType = null
  for (const item of menu) {
    const content = item[0]
    const type = parseInt(content[2])
    const title = content.split(/<\/?h.>/)[1]
    const menuitem = new menuItem(title, type, arrIndex[type]++)

    //判斷當(dāng)前type-1項(xiàng)有沒有內(nèi)容,有的話就加入到前一個(gè)種類的children中去
    if (pre[type - 1]) {
      pre[type - 1].children.push(menuitem)
    }
    //重置當(dāng)前type的項(xiàng)
    pre[type] = menuitem
    minType = minType ?? type
    //如果是最小的h標(biāo)簽,就插入
    if (type === minType) {
      arr.push(menuitem)
    }
  }
  return arr
}

轉(zhuǎn)換的arr結(jié)果如下,可以看到,數(shù)組中保存了兩個(gè)頂層目錄,children保存了內(nèi)部的子目錄。

Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄

封裝遞歸組件fold-item(在使用之前不要忘了導(dǎo)入自己哦)

<script lang="ts" setup>
import foldItem from './foldItem.vue'   //導(dǎo)入自己
defineProps({
  item: {
    type: Object,
    default: () => ({})
  }
})
</script>
<template>
  <!--  如果有孩子,就渲染成sub-menu(折疊item)-->
  <template v-if="item.children.length">
    <el-sub-menu :index="item.title">
      <template #title>
        <div class="title" v-html="item.title"></div>
      </template>
      <fold-item
        v-for="i in item.children"
        :key="i.title"
        :item="i"
      ></fold-item>
    </el-sub-menu>
  </template>
  <!--  否則就渲染成menu-item-->
  <template v-else>
    <el-menu-item :index="item.title" @click="scrollToItem(item)">
      <template #title>
        <div class="title" v-html="item.title"></div>
      </template>
    </el-menu-item>
  </template>
</template>
<style lang="less" scoped>
.title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

::v-deep.el-menu-item {
  width: 220px;
  line-height: 30px;
  height: 30px;
}
::v-deep.el-sub-menu {
  width: 220px;
}
::v-deep .el-sub-menu__title {
  height: 30px;
  line-height: 30px;
}
</style>

在foldMenu中使用遞歸組件

<script lang="ts" setup>
import foldItem from './foldItem.vue'
defineProps({
  menu: {
    type: Array,
    default: () => []
  }
})
</script>
<template>
  <div class="menu-title">目錄</div>
  <el-menu>
  <!-- 使用遞歸組件 -->
    <fold-item v-for="item in menu" :key="item.title" :item="item"></fold-item>
  </el-menu>
</template>
<style lang="less" scoped>
::v-deep.el-menu {
  border: none;
}
.menu-title {
  text-align: center;
  margin-bottom: 10px;
}
</style>

使用效果

Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄

更復(fù)雜的目錄結(jié)構(gòu)也能勝任

Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄

以上就是關(guān)于“Vue怎么結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI