ant-design-vue导航菜单a-menu的使用解读

 更新时间:2022年10月10日 10:25:35   作者:一羊迁徙  
这篇文章主要介绍了ant-design-vue导航菜单a-menu的使用解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

此文章包含了递归生成三级菜单,刷新状态保留,只展开一个父级菜单等常见问题。

一、效果

可以看到递归生成三级菜单,刷新状态保留,只展开一个父级菜单等常见问题得以解决。我自己的电脑设备老旧,反应缓慢的问题请忽略。

在这里插入图片描述

二、关键的API

说实话遇到问题了不知道该怎么解决,说白了还是不懂得API的使用,对相关的API不够了解,熟悉了API怎么操作都行。下面说说用到但是又容易混淆的API。

1.defaultSelectedKeys 默认选中的key

这里的key对应的是a-menu-item上面绑定的key,如果被选中,会进行导航的跳转以及被给予高亮状态。

2.openKeys 展开的a-sub-menu的key

这里的key对应的是a-sub-menu上面绑定的key。如果绑定在a-menu上,对应的子菜单会打开。

3.selectedKeys 受控选中的key

这里的key对应的是a-menu-item上面绑定的key,如果被选中,会进行导航的跳转以及被给予高亮状态。

与defaultSelectedKeys 有什么区别:

  • 这两个属性为二选一使用,如果同时使用时,defaultSelectedKeys无效,将会以selectedKeys为准。
  • 如果你只是希望指定一个初始化选中的菜单项,请使用defaultSelectedKeys;
  • 如果你需要每次通过传入不同的props改变Menu组件的选中项,请使用selectedKeys。

三、注意事项

此处强调一点,如果是一级以及二级菜单的生成,普通的两层for循环结合递归以及v-if生成即可。

如果是想使用a-menu生成三级或者三级以上的菜单,那么就需要定义在单文件内定义函数式组件。那为什么不推荐单文件的形式定义组件,而是使用函数式组件?

以下是官方文档的说明:

在这里插入图片描述

四、代码

<template>
  <a-layout id="components-layout-demo-custom-trigger" style="height:100%">
    <a-layout-sider theme="light" v-model="collapsed" :trigger="null" collapsible>
      <div >
          <a-menu
            :inlineIndent="inlineIndent"
            :defaultSelectedKeys="[$route.path]"
            :openKeys="openKeys"
            mode="inline"
            :inline-collapsed="collapsed"
            @openChange="onOpenChange"
            @click="menuClick">
            <!-- 菜单遍历的开始 -->
            <template v-for="item in list">
              <!-- 如果当前遍历项没有children,视为子菜单项,注意所有的key都是path用于路由跳转,以及当前选中记录 -->
              <a-menu-item v-if="!item.children" :key="item.path">
                <i :class="item.icon" />
                <span>{{ item.title }}</span>
              </a-menu-item>
              <!-- 否则视为子菜单,传入菜单信息并且运用下面定义的函数式组件 -->
              <sub-menu v-else :key="item.path" :menu-info="item" />
            </template>
        </a-menu>
      </div>
    </a-layout-sider>
    <a-layout>
      <a-layout-content :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }">
        <router-view/>
      </a-layout-content>
    </a-layout>
  </a-layout>
</template>
<script>
import { Menu } from 'ant-design-vue';
// 定义函数式组件
const SubMenu = {
  template: `
      <a-sub-menu :key="menuInfo.path" v-bind="$props" v-on="$listeners">
        <span slot="title">
          <i :class="menuInfo.icon" /><span>{{ menuInfo.title }}</span>
        </span>
        <template v-for="item in menuInfo.children">
          <a-menu-item v-if="!item.children" :key="item.path">
            <i :class="item.icon" />
            <span>{{ item.title }}</span>
          </a-menu-item>
          <sub-menu v-else :key="item.path" :menu-info="item" />
        </template>
      </a-sub-menu>
    `,
  name: 'SubMenu',
  // must add isSubMenu: true 此项必须被定义
  isSubMenu: true,
  props: {
    // 解构a-sub-menu的属性,也就是文章开头提到的为什么使用函数式组件
    ...Menu.SubMenu.props,
    // 接收父级传递过来的菜单信息
    menuInfo: {
      type: Object,
      default: () => ({}),
    },
  },
};
export default {
  data() {
    return {
      // 菜单缩进
      inlineIndent:12,
      // 默认不折叠
      collapsed: false,
      // 全部顶级父节点,用来控制所有父级菜单只展开其中的一项,可用遍历菜单信息进行赋值
      rootSubmenuKeys: ['/infomationManage','/safeInfoManage','/qualityInfoManage'],
      // 展开的父菜单项
      openKeys: [], 
      // 选中的子菜单项
      defaultSelectedKeys: [this.$route.path], 
      // 菜单信息,可从后台获取
      list: [
        {
          key: '1',
          title: '项目信息管理',
          path: '/infomationManage',
          icon:'iconfont icon-information'
        },
        {
          key: '2',
          title: '安全信息管理',
          path: '/safeInfoManage',
          icon:'iconfont icon-anquan',
          children: [
            {
              key: '2.1',
              title: '安全风险管理',
              path: '/safeRisk',
              icon:'',
              children: [
                { 
                  key: '2.1.1',
                  title: '风险分类管理',
                  path: '/riskClassifyManage',
                  icon:'',
                },
                {
                    key: '2.1.2',
                    title: '分类辨识',
                    path: '/classifyIdentity',
                    icon:'',
                }
              ],
            },
          ],
        },
        {
          key: '3',
          title: '质量信息管理',
          path: '/qualityInfoManage',
          icon:'iconfont icon-zhiliang',
          children:[
              {
                  key: '3.1',
                  title: '质量控制点管理',
                  path: '/controlPointManage',
                  icon:'',
              }
          ]
        }
      ],
    }
  },
  created(){
    // 将从缓存中取出openKeys
    const openKeys = window.sessionStorage.getItem('openKeys')
    if(openKeys){
      // 存在即赋值
      this.openKeys = JSON.parse(openKeys)
    }
  },
  methods: {
    // 点击菜单,路由跳转,注意的是当点击MenuItem才会触发此函数
    menuClick({ item, key, keyPath }) {
      // 获取到当前的key,并且跳转
      this.$router.push({
        path: key
      })
    },
    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] : [];
      }
    },
  },
  // 注册局部组件
  components: {
    'sub-menu': SubMenu,
  },
};
</script>
<style>
</style>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue-Element-Admin前端接入SSO的方法步骤

    Vue-Element-Admin前端接入SSO的方法步骤

    本文主要介绍了Vue-Element-Admin前端接入SSO的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • Vue2.0 ES6语法降级ES5的操作

    Vue2.0 ES6语法降级ES5的操作

    这篇文章主要介绍了Vue2.0 ES6语法降级ES5的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • vue实现从外部修改组件内部的变量的值

    vue实现从外部修改组件内部的变量的值

    这篇文章主要介绍了vue实现从外部修改组件内部的变量的值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • vue框架和react框架的区别以及各自的应用场景使用

    vue框架和react框架的区别以及各自的应用场景使用

    这篇文章主要介绍了vue框架和react框架的区别以及各自的应用场景使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • vue3中vite.config.js相关常用配置超详细讲解

    vue3中vite.config.js相关常用配置超详细讲解

    在Vue3项目中vite.config.js文件是Vite构建工具的配置文件,它用于定义项目的构建和开发选项,这篇文章主要介绍了vue3中vite.config.js相关常用配置的相关资料,需要的朋友可以参考下
    2025-04-04
  • VueCli4项目配置反向代理proxy的方法步骤

    VueCli4项目配置反向代理proxy的方法步骤

    这篇文章主要介绍了VueCli4项目配置反向代理proxy的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • Vue2.0/3.0双向数据绑定的实现原理详解

    Vue2.0/3.0双向数据绑定的实现原理详解

    这篇文章主要给大家介绍了关于Vue2.0/3.0双向数据绑定的实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Vuex数据的存储与获取方式

    Vuex数据的存储与获取方式

    这篇文章主要介绍了Vuex数据的存储与获取方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 谈谈Vue中的nextTick

    谈谈Vue中的nextTick

    Vue.nextTick是Vue官方给我们提供的一个API(方法),作用是在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM
    2021-04-04
  • Vue3实现获取验证码按钮倒计时效果

    Vue3实现获取验证码按钮倒计时效果

    这篇文章主要介绍了Vue3实现获取验证码按钮倒计时效果,用户点击获取验证码按钮,发送请求给后端,按钮失效,并且开始倒计时60秒;在此期间,用户无法再次点击按钮,即使用户刷新页面,倒计时依然存在,直到倒计时完毕,按钮恢复,感兴趣的小伙伴跟着小编一起来看看吧
    2024-10-10

最新评论