基於vue.ant.design的單檔案方式遞迴生成選單

田小菜發表於2019-10-07

效果圖

基於vue.ant.design的單檔案方式遞迴生成選單

準備知識

瞭解v-bind="$attrs" 和  v-on="$listeners"
複製程式碼

www.cnblogs.com/yuzhongyu/p…

上手程式碼

  • AppMenu.vue
    // AppMenu.vue
    // 側邊欄的使用
    <template>
         <div>
            <a-menu
                mode="inline"
                theme="dark"
                :forceSubMenuRender="true"
                :inlineIndent="10"
            >
                <template v-for="item in menuList">
                    <a-menu-item 
                        v-if="!item.children" 
                        :key="item.id"  
                        @click="itemTick(item.id)"
                    >
                        <a-icon v-if="item.icon" :component="item.icon"/>
                        <span>{{ item.menuName }}</span>
                    </a-menu-item>
                    <sub-menu 
                        v-else 
                        :menu-info="item" 
                        :key="item.id" 
                        @titleClick="titleClick" 
                        @itemTick="itemTick"
                    >
                    </sub-menu>
                </template>
            </a-menu>
        </div>
    </template>
    
<script>
import { Menu, Icon } from 'ant-design-vue'
import burialDesign from "@/assets/picture/icon_burial_design.svg?component";
import SubMenu from './SubMenu.vue';
export default {
    name: 'AppMenu',
    components: {
        'a-menu': Menu,
        'a-sub-menu': Menu.SubMenu,
        'a-menu-item': Menu.Item,
        'a-icon': Icon,
        SubMenu
    },
    data () {
        return {
            menuList: [
                {
                    children: [
                        {
                            id: "menu2",
                            menuName: "列表22",
                            path: "fault",
                            pid: "menu1",
                            children: [{
                                id: "menu3",
                                menuName: "列表33",
                                path: "fault",
                                pid: "menu2",
                            }]
                        }
                    ],
                    icon: burialDesign,
                    id: 'menu1',
                    menuName: '管理11',
                },
                {
                    children: [
                        {
                            id: "etl2",
                            menuName: "ETL22",
                            path: "etl",
                            pid: "etl1",
                            children: [{
                                id: "etl3",
                                menuName: "ETL33",
                                path: "etl",
                                pid: "etl2",
                                    children: [{
                                        id: "etl4",
                                        menuName: "ETL44",
                                        path: "etll4",
                                        pid: "etl3",
                                    }]
                            }]
                        }
                    ],
                    icon: burialDesign,
                    id: 'etl1',
                    menuName: 'ETL11',
                },
                {
                    path: 'test',
                    icon: burialDesign,
                    id: 'test1',
                    menuName: '測試11',
                },
                {
                    children: [
                        {
                            id: "444444",
                            menuName: "444",
                            path: "44444",
                            pid: "444",
                           
                        }
                    ],
                    icon: burialDesign,
                    id: '444',
                    menuName: '444',
                },
            ]
        }
    },
}
複製程式碼
  • SubMenu.vue
<template>
    <a-sub-menu
        :key="menuInfo.id"
        v-bind="$props"
        v-on="$listeners"
    >
        <span slot="title">
            <a-icon v-if="menuInfo.icon" :component="menuInfo.icon"/>
            <span>{{ menuInfo.menuName }}</span>
        </span>
        <template v-for="item in menuInfo.children">
            <a-menu-item
                v-if="!item.children"
                :key="item.id"
                @click="tick(item.id)"
            >
                <a-icon v-if="item.icon" :component="item.icon"/>
                <span>{{ item.menuName }}</span>
            </a-menu-item>
            <sub-menu
                v-else
                :key="item.id"
                :menu-info="item"
                @titleClick="changeMenu"
                v-on="$listeners"
            />
        </template>
    </a-sub-menu>
</template>
<script>
import { Menu, Icon } from 'ant-design-vue'
export default {
    name: 'SubMenu',
    // must add isSubMenu: true
    isSubMenu: true, // $props.isSubMenu
    props: {
        ...Menu.SubMenu.props, // 
        // Cannot overlap with properties within Menu.SubMenu.props
        menuInfo: { 
            type: Object,
            default: ()=> {}
        },
        selectedKeys: {
            type: Array,
            default: ()=> []
        }
    },
    components: {
        'a-menu': Menu,
        'a-sub-menu': Menu.SubMenu,
        'a-menu-item': Menu.Item,
        'a-icon': Icon
    },
    methods: {
        // 點選子選單標題
		changeMenu(menu) {
            // console.log('展開menu===',menu)
            // console.log('selectedKeys===',this.selectedKeys)
            this.$emit('titleClick',menu);
        },
        tick(id) {
            console.log('$listeners===',this.$listeners);
            console.log('$attrs===',this.$attrs);
            console.log('$props===',this.$props);
            
            // console.log('最後一層id===',id)
            this.$emit('itemTick',id);
        }
    }
};
</script>
複製程式碼

相關文章