【Ant Design Vue 】之Menu菜单

文章目录

    • 常用属性
    • 常用事件
    • 递归嵌套多级菜单
    • 效果

版本ant-design-vue: "^1.7.4",

常用属性

属性 说明 默认值
mode 菜单类型,现在支持垂直、水平、和内嵌模式三种 vertical
inlineCollapsed inline 时菜单是否收起状态
theme 主题颜色(light/dark) light
openKeys(.sync) 当前展开的 SubMenu 菜单项 key 数组
defaultOpenKeys 初始展开的 SubMenu 菜单项 key 数组
selectedKeys(v-model) 当前选中的菜单项 key 数组
defaultSelectedKeys 初始选中的菜单项 key 数组

说明
defaultSelectedKeys 是默认选中的keya-menu-item上绑定的key),被选中会有高亮的显示效果;selectedKeys 也是一样的作用,不要同时使用,区别在于如果只希望指定一个初始化的菜单选项就使用defaultSelectedKeys,如果需要通过自己修改数据来选中菜单的选中项就使用selectedKeys
openKeysdefaultOpenKeys也是同理)

常用事件

openChangeMenu的事件,SubMenu 展开/关闭的回调

递归嵌套多级菜单

若只有两级菜单则直接使用v-forv-if指令即可完成;若菜单级数≥3则需要使用函数式组件。具体原因官网已经做了说明:

Before v2.0, 因组件内部会动态更改a-sub-menu的属性,如果拆分成单文件,无法将属性挂载到a-sub-menu上,你需要自行声明属性并挂载。为了方便,避免属性的声明,我们推荐使用函数式组件。

代码
App.vue (测试就随便在App.vue里写了)

<template>
    <div id="app">
        <div style="width: 256px">
            <a-button type="primary" style="margin-bottom: 16px" @click="toggleCollapsed">
            <a-icon :type="collapsed ? 'menu-unfold' : 'menu-fold'" />
            a-button>
            <a-menu
                :defaultSelectedKeys="[$route.path]"
                :openKeys="openKeys"
                mode="inline"
                theme="dark"
                :inline-collapsed="collapsed"
                @openChange="onOpenChange"
                @click="menuClick"
            >
                <template v-for="item in list">
                    <a-menu-item v-if="!item.children" :key="item.path">
                        <a-icon type="pie-chart" />
                        <span>{
    { item.title }}span>
                    a-menu-item>
                    <sub-menu v-else :key="item.path" :menu-info="item" />
                template>
            a-menu>
        div>
        <router-view/>
    div>
template>

<script>
import {
       Menu } from 'ant-design-vue';
const SubMenu = {
      
  template: `
      
        
          {
       { menuInfo.title }}
        
        
      
    `,
  name: 'SubMenu',
  // must add isSubMenu: true 此项必须被定义
  isSubMenu: true,
  props: {
      
    // 解构a-sub-menu的属性,也就是文章开头提到的为什么使用函数式组件
    ...Menu.SubMenu.props,
    // Cannot overlap with properties within Menu.SubMenu.props
    menuInfo: {
      
      type: Object,
      default: () => ({
      }),
    },
  },
};

export default {
      
    name: "App",
    components: {
      
        'sub-menu': SubMenu,
    },
    data() {
      
        return {
      
            collapsed: false,
            openKeys: [],
            rootSubmenuKeys: ['/user'],
            list: [
                {
      
                    key: '1',
                    title: '信息管理',
                    path: '/info',
                },
                {
      
                    key: '2',
                    title: '用户管理',
                    path: '/user',
                    children: [
                        {
       
                            key: '2.1',
                            title: '后台用户',
                            path: '/adminUser',
                            children: [
                                {
       
                                    key: '2.1.1',
                                    title: '新增用户',
                                    path: '/addAdminUser',
                                    children: [
                                        {
      
                                            key: '2.1.1。1',
                                            title: '用户xx',
                                            path: '/addAdminUserXX',
                                        }
                                    ]
                                }
                            ]
                        },
                        {
       
                            key: '2.2',
                            title: '前台用户',
                            path: '/frontUser',
                        }
                    ]
                }
            ],
        };
    },
    created(){
      
        const openKeys = window.sessionStorage.getItem('openKeys')
        if(openKeys){
      
            this.openKeys = JSON.parse(openKeys)
        }
    },
    methods: {
      
        toggleCollapsed() {
      
            this.collapsed = !this.collapsed;
        },
        onOpenChange(openKeys) {
      
            // 将当前打开的父级菜单存入缓存中
            window.sessionStorage.setItem('openKeys', JSON.stringify(openKeys))
            //  控制只打开一个
            const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1);
            if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
      
                this.openKeys = openKeys;
            } else {
      
                this.openKeys = latestOpenKey ? [latestOpenKey] : [];
            }
        },
        menuClick({
      key}) {
      
            // 获取到当前的key,并且跳转
            this.$router.push({
      
                path: key
            })
        },
    }
};
script>

<style>
#app {
      
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding: 50px;
}
style>

这里省略了router配置,相信在座的各位也会!(不会的底下留言,包教包会!)

如果vue报编译错误You are using the runtime-only build of Vue,可以在vue的配置文件里加一行runtimeCompiler: true,重新运行即可。

如果点击同一个菜单报错了NavigationDuplicated: Avoided redundant navigation to current location,需要修改下Router设置(router/index.js):

const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
     
    return originalPush.call(this, location).catch(err => err)
}

效果

【Ant Design Vue 】之Menu菜单_第1张图片
自动渲染多级嵌套菜单;刷新会保存选中的菜单;点击菜单,收起其他展开的所有菜单。

你可能感兴趣的:(Vue,vue,ant,design,menu)