vue-cli3 + elementui 搭建后臺(tái)管理界面(五)-遞歸生成側(cè)欄路由

1 定義多級(jí)菜單

修改 src/router/index.js 的 / 路由

  {
    path: '/',
    redirect: '/dashboard',
    name: 'Container',
    component: Container,
    children: [
      {path: 'dashboard', name: '首頁', component: Dashboard, 
        children: [
          {path: 'dashboard1', name: '首頁1', component: Dashboard,},
          {path: 'dashboard2', name: '首頁2', component: Dashboard,
            children: [
              {path: 'dashboard21', name: '首頁21', component: Dashboard,},
              {path: 'dashboard22', name: '首頁22', component: Dashboard, },
            ] },
        ]
      },
      {path: 'article', name: '文章', component: Article, },
    ]
  }

2 抽出Sidebar組件

生成的遞歸路由放在側(cè)邊欄,因此抽取 sidebar 組件绑洛,sidebar 包含logo和 遞歸路由
再抽取 SidebarItem 為單獨(dú)的路由組件,方便遞歸調(diào)用

2.1 Sidebar

Sidebar 接收collapse萍虽、路由數(shù)組膜蠢,同時(shí)引入 SidebarItem 組件

子組件傳入:

  • barIdx: 當(dāng)前路由的索引,用來定位子菜單
  • subroute: 路由對(duì)象
  • fatherpath: 父路徑滋恬,如 /、 /a/b
<template>
  <div>
    <div class="app-side-logo">
      <img src="@/assets/logo.png"
          :width="collapse ? '60' : '60'"
          height="60" />
    </div>

    <el-menu class="el-menu-vertical-demo"
          :default-active="defaultActive"
            router
            :collapse="collapse"
            >
      <SidebarItem v-for="(item, idx) in routes" 
        :subroute="item"
        :fatherpath="fatherPath"
        :barIdx="idx" :key="idx" />
    </el-menu>
  </div>
</template>

<script>
import SidebarItem from './SidebarItem'
export default {
  naem: "Sidebar",
  components: {
    SidebarItem
  },
  props: {
    collapse: {
      type: Boolean
    },
    routes: {
      type: Array
    }
  },
  computed: {
     // 首次進(jìn)入頁面時(shí)展開當(dāng)前頁面所屬的菜單
    defaultActive(){
      return this.$route.path
    },
    fatherPath(){
      // 這里直接獲取路由配置的 '/' 項(xiàng)
      return this.$router.options.routes[1].path
    }
  }
}
</script>

<style>

</style>

2.2 SidebarItem

SidebarItem 接收路由抱究、父路由path恢氯、父級(jí)idx,然后遞歸調(diào)用自身

<template>
  <!-- 如果當(dāng)前 subroute 有子節(jié)點(diǎn) -->
  <el-submenu v-if="!subroute.hidden && subroute.children && subroute.children.length > 0"
    :index="genPath(fatherpath, subroute.path)">
    <!-- 創(chuàng)建菜單分組 -->
    <template slot="title">
      <i class="el-icon-menu"></i>
      <span slot="title">{{subroute.name}}</span>
    </template>

    <!-- 遞歸調(diào)用自身鼓寺,直到 subroute 不含子節(jié)點(diǎn) -->
    <SidebarItem v-for="(submenu, subidx) in subroute.children"
      :subroute="submenu"
      :fatherpath="genPath(fatherpath, subroute.path)"
      :barIdx="subidx" 
      :key="barIdx + '-' + subidx" 
      />
  </el-submenu>

  <!-- 當(dāng)前節(jié)點(diǎn)不含子節(jié)點(diǎn)且非隱藏 -->
  <el-menu-item style="font-weight: 400"
    v-else-if="!subroute.hidden"
    :index="genPath(fatherpath, subroute.path)"
    >{{subroute.name}}
  </el-menu-item>

  <el-menu-item style="font-weight: 400"
    v-else
    :index="genPath(fatherpath, subroute.path)"
    >{{ subroute.name }}
  </el-menu-item>
</template>

<script>
export default {
  name: 'SidebarItem',
  props: {
    subroute: {
      type: Object
    },
    barIdx: {
      type: [String, Number]
    },
    fatherpath: {
      type: String
    }
  },
  computed: {
    // 默認(rèn)激活的路由, 用來激活菜單選中狀態(tài)
    defaultActive: function(){
      return this.$route.path
    },
  },
  methods: {
    // 生成側(cè)邊欄路由勋拟,格式: /a/b/c
    genPath: function(){
      let arr = [ ...arguments ]
      let path = arr.map(v => {
          while (v[0] === '/'){
            v = v.substring(1)
          }
          while(v[-1] === '/'){
            v = v.substring(0, v.length)
          }
        return v 
      }).join('/')
      path = path[0] === '/' ? path : '/'+path
      return path
    },
    handleOpen: function(key, keyPath) {
      console.log(key, keyPath)
    },
    handleClose: function(key, keyPath) {
      console.log(key, keyPath)
    }
  },
  mounted: function(){
    console.log('sidebar routes: ', this.routes)
  }
}
</script>

<style>
</style>

3 項(xiàng)目結(jié)構(gòu)

此時(shí) src 的目錄結(jié)構(gòu)

│  App.vue
│  main.js
├─assets
│      logo.png
├─components
│      HelloWorld.vue
│      Sidebar.vue
│      SidebarItem.vue
├─container
│      Container.vue
├─router
│      index.js
├─styles
│      index.scss
└─views
    │  TheLogin.vue
    ├─article
    │      index.vue
    └─dashboard
            index.vue

4 修改容器配置

src/container/Container.vue 引入 Sidebar 組件

<template>
<!-- ... -->
<el-aside class="app-side app-side-left"
          :class="isCollapse ? 'app-side-collapsed' : 'app-side-expanded'">
  <Sidebar :collapse="isCollapse" :routes="$router.options.routes[1].children"/>
</el-aside>
<!-- ... -->
</template>
<script>
import Sidebar from '@/components/Sidebar'
export default {
  name: 'Container',
  components: {
    Sidebar
  },
/** ... */
</script>

頁面效果


image
image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市妈候,隨后出現(xiàn)的幾起案子敢靡,更是在濱河造成了極大的恐慌,老刑警劉巖苦银,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啸胧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡幔虏,警方通過查閱死者的電腦和手機(jī)纺念,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來想括,“玉大人陷谱,你說我怎么就攤上這事∩冢” “怎么了烟逊?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵渣窜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我焙格,道長(zhǎng)图毕,這世上最難降的妖魔是什么夷都? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任眷唉,我火速辦了婚禮,結(jié)果婚禮上囤官,老公的妹妹穿的比我還像新娘冬阳。我一直安慰自己,他們只是感情好党饮,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布肝陪。 她就那樣靜靜地躺著,像睡著了一般刑顺。 火紅的嫁衣襯著肌膚如雪氯窍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天蹲堂,我揣著相機(jī)與錄音狼讨,去河邊找鬼。 笑死柒竞,一個(gè)胖子當(dāng)著我的面吹牛政供,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播朽基,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼布隔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了稼虎?” 一聲冷哼從身側(cè)響起衅檀,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎霎俩,沒想到半個(gè)月后哀军,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茸苇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年排苍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片学密。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡淘衙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腻暮,到底是詐尸還是另有隱情彤守,我是刑警寧澤毯侦,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站具垫,受9級(jí)特大地震影響侈离,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜筝蚕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一卦碾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧起宽,春花似錦洲胖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至腐晾,卻和暖如春叉弦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背藻糖。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國打工淹冰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颖御。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓榄棵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親潘拱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疹鳄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容