AntDesign vue學習筆記(五)導航菜單動態加載


一、使用官方例子

<template>
  <div style="width: 256px">
    <a-button type="primary" @click="toggleCollapsed" style="margin-bottom: 16px">
      <a-icon :type="collapsed ? 'menu-unfold' : 'menu-fold'" />
    </a-button>
    <a-menu
      :defaultSelectedKeys="['1']"
      :defaultOpenKeys="['2']"
      mode="inline"
      theme="dark"
      :inlineCollapsed="collapsed"
    >
      <template v-for="item in list">
        <a-menu-item v-if="!item.children" :key="item.key">
          <a-icon type="pie-chart" />
          <span>{{ item.title }}</span>
        </a-menu-item>
        <sub-menu v-else :menu-info="item" :key="item.key" />
      </template>
    </a-menu>
  </div>
</template>

<script>
// recommend use functional component
// <template functional>
//   <a-sub-menu :key="props.menuInfo.key">
//     <span slot="title">
//       <a-icon type="mail" /><span>{{ props.menuInfo.title }}</span>
//     </span>
//     <template v-for="item in props.menuInfo.children">
//       <a-menu-item v-if="!item.children" :key="item.key">
//         <a-icon type="pie-chart" />
//         <span>{{ item.title }}</span>
//       </a-menu-item>
//       <sub-menu v-else :key="item.key" :menu-info="item" />
//     </template>
//   </a-sub-menu>
// </template>
// export default {
//   props: ['menuInfo'],
// };

import { Menu } from 'ant-design-vue';
const SubMenu = {
  template: `
      <a-sub-menu :key="menuInfo.key" v-bind="$props" v-on="$listeners">
        <span slot="title">
          <a-icon type="mail" /><span>{{ menuInfo.title }}</span>
        </span>
        <template v-for="item in menuInfo.children">
          <a-menu-item v-if="!item.children" :key="item.key">
            <a-icon type="pie-chart" />
            <span>{{ item.title }}</span>
          </a-menu-item>
          <sub-menu v-else :key="item.key" :menu-info="item" />
        </template>
      </a-sub-menu>
    `,
  name: 'SubMenu',
  // must add isSubMenu: true
  isSubMenu: true,
  props: {
    ...Menu.SubMenu.props,
    // Cannot overlap with properties within Menu.SubMenu.props
    menuInfo: {
      type: Object,
      default: () => ({}),
    },
  },
};
export default {
  components: {
    'sub-menu': SubMenu,
  },
  data() {
    return {
      collapsed: false,
      list: [
        {
          key: '1',
          title: 'Option 1',
        },
        {
          key: '2',
          title: 'Navigation 2',
          children: [
            {
              key: '2.1',
              title: 'Navigation 3',
              children: [{ key: '2.1.1', title: 'Option 2.1.1' }],
            },
          ],
        },
      ],
    };
  },
  methods: {
    toggleCollapsed() {
      this.collapsed = !this.collapsed;
    },
  },
};
</script>

增加@click事件

 

 

 

點擊彈出效果如下圖,注意:這里@click后不能直接寫@click="alert('a')",會報TypeError: _vm.alert is not a function

二、其他實現方法

一般的后台系統都有一個樹形導航菜單,具體實現如下,主要參考
https://my.oschina.net/u/4131669/blog/3048416

menuList: [
        {
          'name': '首頁',
          'url': 'http://192.168.1.100:9999',
          'iconType': 'laptop',
          'sidebars': []
        },
        {
          'name': '企業信息',
          'url': null,
          'iconType': 'bars',
          'sidebars': [
            {
              'name': '公司管理',
              'url': 'http://192.168.1.100:8890//swagger-ui.html',
              'iconType': 'laptop',
              'sidebars': []
            }
          ]
        },
        {
          'name': '工程管理',
          'url': 'http://192.168.1.100:9999/about',
          'iconType': 'laptop',
          'sidebars': []
        }
      ]
    }

1、定義sub-menu組件,用於遞歸顯示多級菜單

<template functional>
  <a-sub-menu :key="props.menuInfo.name" >
    <span slot="title">
      <a-icon type="folder" />
      <span>{{ props.menuInfo.name +','+props.menuInfo.sidebars.length}}</span>
    </span>
    <template v-for="item in props.menuInfo.sidebars">
      <a-menu-item
        v-if="!item.sidebars.length"
        :key="item.key">
        <span>{{ item.name }}</span>
      </a-menu-item>
    </template>
  </a-sub-menu>
</template>
<script>
export default {
  name: 'SubMenu',
  props: ['menuInfo']
}

不能在函數式組件里定義事件並通過@click掉用,但是可以調用父組件的事件,方法

<template functional>
  <a-sub-menu :key="props.menuInfo.name" @click=parent.fetchMenu()>
...
原因是:
函數式組件沒有實例,事件只能由父組件傳遞。

template functional標志該組件為函數化組件

2、在Mainfrm中引入組件

import SubMenu from './SubMenu'
components: {
SubMenu
}

 

3、menu模板
<template v-for="item in menuList">
  <a-menu-item v-if="!item.sidebars.length" :key="item.name">
     <a-icon :type="item.iconType" />
        <span>{{item.name}}</span>
  </a-menu-item>
  <sub-menu v-else :menu-info="item" :key="item.name"/>
</template>

 6、最終實現效果如下

 

 

 

 

地址:https://www.jianshu.com/p/c549c3d0f595這篇文章的遞歸方法點擊事件顯示是正常的,他這個用的是原生html元素,需要美化界面,代碼如下

list: [
{
    "id": "1",
    "menuName": "項目管理",
    "childTree": [{
        "menuName": "項目進度",
        "childTree": [{
            "menuName": "項目一",
            "childTree": [{ "menuName": "詳細信息" }]
        }]
    }, {
        "menuName": "任務安排"
    }]
}, 
{
    "id": "2",
    "menuName": "數據統計"
}, 
{
    "id": "3",
    "menuName": "人員管理"
}]
// 子組件代碼
<template>
    <li>
        <span @click="toggle">
            {{ model.menuName }}
        </span>
        <ul v-if="isFolder" v-show="open">
            <items v-for="(item, index) in model.childTree" :model="item" :key="index"></items>
        </ul>
    </li>
</template>

<script type="text/javascript">
    export default {
        // 組件遞歸必要條件,name屬性
        name: 'items',
        props: ['model'],
        data() {
            return {
                // 控制子列表的顯示隱藏
                open: false
            }
        },
        computed: {
            // 是否還有子列表需要渲染,作為v-if的判斷條件
            isFolder() {
                return this.model.childTree && this.model.childTree.length
            }
        },
        methods: {
            // 切換列表顯示隱藏的方法
            toggle() {
                if(this.isFolder) {
                    this.open = !this.open
                }
            },
        }
    }
</script>
<template>
    <div>
        <ul>
            <items v-for="(model, index) in list" :model="model" :key="index"></items>
        </ul>
    </div>
</template>

<script type="text/javascript">
    components: {
        Items
    },
    data() {
        return {
            list: ...
        }
    }
</script>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM