首頁 > 軟體

vue遞迴元件實現elementUI多級選單

2022-07-14 14:01:15

 本文範例為大家分享了vue遞迴元件實現elementUI多級選單的具體程式碼,供大家參考,具體內容如下

先看效果:

一、子元件

<template>
    <div class="myDiv">
        <!-- 這裡的listAll用於接收父元件傳遞進來的選單列表 -->
        <template v-for="(item,i) in listAll">
            <!-- 有child就顯示child的下拉型選單,有小箭頭 -->
            <el-submenu :index="item.index" :key="i" v-if="item.child.length!=0">
                <template slot="title">
                    <img :src="item.img" alt="">
                    <span>{{item.title}}</span>
                </template>
                <!-- 再次呼叫自身元件,傳入子集,進行迴圈遞迴呼叫 -->
                <Menu :listAll="item.child"></Menu>
            </el-submenu>
            <!-- 沒有child,就顯示單個目錄,沒有小箭頭 -->
            <el-menu-item :index="item.index" v-else :key="i" @click="handleSelect(item.path,item.title,item.index)">
                <span slot="title"><img :src="item.img" alt="">{{item.title}}</span>
            </el-menu-item>
        </template>
    </div>
</template>
 
<script>
export default {
    name: 'Menu',
    components: {},
    props: ['listAll'],
    data() {
        return {
            realList: this.listAll,
        }
    },
    methods: {
        //設定路由跳轉
        handleSelect(path, name, selfIndex) {
            this.$router.push(
                {
                    path: "/" + path,
                    query: {
                        r_n: name,
                        index: selfIndex
                    }
                }
            )
        },
       
    },
}
</script>

二、選單資料準備

選單中包含索引,圖片,名稱,跳轉路徑,這裡我給出一部分資料,路由直接用數位了,你們最好定義為元件的英文名稱,這樣方便維護。

export function menuJson() {
  var data = [{
    title: "後設資料管理",
    img: "../../../static/img/manager.png",
    index: '1',
    child: [
      {
        "title": "後設資料資訊描述管理", "path": "main/02/005", "img": "../../../static/img/manager.png", "index": "1-2", "child": []
      },
      {
        "title": "後設資料分組定義管理", "path": "main/02/007", "img": "../../../static/img/manager.png", "index": "1-3", "child": []
      },
      {
        "title": "後設資料資訊管理", "path": "main/02", "img": "../../../static/img/manager.png", "index": "1-1", "child": [
          { "title": "採集後設資料", "path": "main/02/001", "index": "1-1-1", "img": "../../../static/img/blood.png", "child": [] },
          { "title": "元模型", "path": "main/02/004", "index": "1-2-1", "img": "../../../static/img/blood.png", "child": [] },
        ]
      },
 
      {
        "title": "後設資料統計分析管理", "path": "main/01", "index": "1-4", "img": "../../../static/img/manager.png", "child": [
          { "title": "後設資料變更管理", "path": "main/01/001", "index": "1-4-1", "img": "../../../static/img/blood.png", "child": [] },
          { "title": "資料地圖", "path": "main/01/002", "index": "1-4-2", "img": "../../../static/img/blood.png", "child": [] },
          {
            "title": "後設資料分析", "path": "main/01/003", "index": "1-4-3", "img": "../../../static/img/yuanfenxi.png", "child": [
 
              { "title": "血緣分析", "path": "main/01/003/0001", "index": "1-4-3-1", "img": "../../../static/img/blood.png", "child": [] },
              { "title": "屬性差異分析", "path": "main/01/003/0003", "index": "1-4-3-2", "img": "../../../static/img/chayi.png", "child": [] },
              { "title": "影響分析", "path": "main/01/003/0004", "index": "1-4-3-3", "img": "../../../static/img/impact.png", "child": [] },
            ]
          },
 
        ]
      },
    ]
  },
  {
    title: "規則管理",
    img: "../../../static/img/manager.png",
    index: '2',
    child: [
      { "title": "資料介面定義管理", "index": "2-1", "path": "main/03/001", "img": "../../../static/img/source.png", "child": [] },
      { "title": "資料轉換規則管理", "index": "2-2", "path": "main/03/004", "img": "../../../static/img/modify.png", "child": [] },
    ]
  }
  ]
  return data
}

三、父元件呼叫

<template>
    <div class="content menu">
        <div class="menu_com" :style="{height:scrollHeight+'px'}">
            <el-col :span="24">
                <el-menu :default-active="activeIndex" class="el-menu-vertical-demo" :default-openeds="defalutIndex" background-color="#003289" text-color="#fff" active-text-color="#ffd04b">
                    //呼叫子元件
                    <Menu :listAll="listAll"></Menu>
                </el-menu>
            </el-col>
        </div>
    </div>
</template>
 
<script>
import Menu from './menu'
import { menuJson } from '../../assets/common/http' //呼叫js檔案中的選單資料
export default {
    name: "Menus",
    mixins: [mixin],
    components: { Menu },
    data() {
        return {
            scrollHeight: 400,
            listAll: [],
            activeIndex: "-1",
            defalutIndex: []
        }
    },
    created() {
        //設定點選選單的索引,可以使得重新整理後選單仍保持原來檢視的頁面
        this.activeIndex = String(this.$route.query.index);
        this.listAll = menuJson() //通過呼叫函數menuJson,獲取選單
    },
    watch: {
        $route(to, from) {
            this.activeIndex = this.$route.query.index;
        }
    },
}
</script>
 
<style scoped lang="less">
@color: #003289;
    .menu {
        background: @color;
 
        > div {
            width: 100%;
            padding-top: 20px;
            // height: 100%;
            color: #ffffff;
            overflow-y: scroll;
            overflow-x: hidden;
            &::-webkit-scrollbar {
                display: none;
            }
            h1 {
                font-size: 20px;
                text-align: center;
                padding: 15px 0 25px 0;
            }
        }
    }
    .el-menu-demo {
        position: absolute;
        height: 58px !important;
        left: 25%;
        top: 0%;
    }
 
</style>

補充(麵包屑的展示):

有選單,肯定需要麵包屑的展示,例如

這裡我用的方法是,根據當前頁面名稱,從樹形選單資料中查詢它的所有父級來實現麵包屑導航欄的展示。

html:

<el-breadcrumb separator-class="el-icon-arrow-right">
    <el-breadcrumb-item v-for="(item,index) in listMenu" :key="index">{{item}}</el-breadcrumb-item>
</el-breadcrumb>

methods:

methods: {
 //獲取樹形資料的某個元素的所有父節點
        getTreePath(tree, func, path) {
            if (!tree) return []
            for (const data of tree) {
                // 這裡按照你的需求來存放最後返回的內容吧
                //這裡的title是我的選單資料裡面的名稱欄位,你可以改成你的
                path.push(data.title)
                if (func(data)) return path
                if (data.child) {
                    //獲取到子資料,遞迴呼叫
                    const findChildren = this.getTreePath(data.child, func, path)
                    if (findChildren.length) return findChildren
                }
                path.pop()
            }
            return []
        },
        // 獲取麵包屑
        getNavList() {
            var name = this.$route.query.r_n //先獲取當前路由名稱
            var tree = menuJson()  //獲取選單資料,menuJson這個函數上面用了,返回的事選單資料
            this.path = [] //path用於存放所有父級,呼叫前需要清空
            //data => data.title === name查詢資料中的title是否和當前路由名稱相等
            this.getTreePath(tree, data => data.title === name, this.path)
            this.listMenu = this.path  //找到之後賦值給麵包屑路由陣列
            console.log(this.listMenu)
        }
    }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com