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

目录
  • 一、效果
  • 二、关键的API
  • 三、注意事项
  • 四、代码

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

一、效果

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

二、关键的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>

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

(0)

相关推荐

  • vue3中使用ant-design-vue的layout组件实现动态导航栏和面包屑功能

    目录 0 前言 1 准备工作 1.1 安装ant-design-vue 1.2 安装图标组件包 2 选择组件 3 路由文件 4 Vue导航页面 5 最终效果 0 前言 最近在自己搞一个前后端小项目,前端想使用ant-design-vue的layout组件实现动态导航栏和面包屑,但是网上的资料较少,所以我就自己整合实现了一下,在此记录分享. 1 准备工作 基于一个新建的Vue3项目上实现. 1.1 安装ant-design-vue 官方文档:Components Overview - Ant De

  • ant-design-vue动态表格合并案例

    目录 前言 数据格式 ant-desgin-vue表格提供的api 合并单元格算法实现 效果展示 前言 最近接到一个需求,要把后端传过来的数据动态展示在表格上面,并且支持前端筛选,相同数据进行单元格合并, 最终实现的效果如下: 数据格式 后端会返回给我们一个数组,数组的每一项格式是这样,在这个需求里,我们需要对 title,department,bugType 这三个字段相同的值的单元格进行合并 { fixCount: 0, id: 0, codeType: '新代码', bugType: 'u

  • ant-design-vue中设置Table每页显示的条目数量方式

    目录 ant-design-vue设置Table每页显示的条目数量 ant-design-vue a-table的分页 ant-design-vue设置Table每页显示的条目数量 新项目中设置分页条数遇到点问题,查阅百度发现都是使用: pagination="false"禁用table的分页功能,自己重新封装一个分页,其实duck不必这么做,官方文档中提供了一个pageSize,自然有自己的妙用!  <a-table :columns="columns" :

  • ant design vue导航菜单与路由配置操作

    此功能包含: 1.根据动态路由自动展开与自动选择对应路由所在页面菜单 2.只展开一个子菜单 3.兄弟组件控制菜单与路由 <a-menu :openKeys="openKeys" :selectedKeys="selectedKeys" mode="inline" theme="dark" :inlineCollapsed="$store.state.isCollapse" @click='select

  • vue 导航菜单刷新状态不消失,显示对应的路由界面操作

    使用vue element-ui框架构建公共导航栏(https://element.eleme.cn/#/zh-CN/component/menu) 按F5刷新就会返回默认定义的路由,使用 "$route.path" 刷新后还是在最新的一个路由: <el-menu :default-active="$route.path"></el-menu> 补充知识:vue 动态菜单 刷新空白 解决方案 1.先确认自己在route.js 或者 main.

  • Ant Design Vue 添加区分中英文的长度校验功能

    原本的maxLength属性是不区分全角/半角字符的,对于一些可中英文混合输入地方而言不太合适.所以想找一个可区分全角/半角字符的校验,而且要保证一定的可重用性. 百度搜了一圈都没找到合适的现成的解决方案,所以自己试着基于v-decorator的自定义校验validator实现了一下,核心代码如下: 校验插件 const validators = { /** * 可区分全角字符/半角字符的长度校验. * @param min * @param max * @returns {Function}

  • Ant design vue table 单击行选中 勾选checkbox教程

    最近了解Ant design 设计table 单击行选中checkedbox功能,相比于element的 @row-click 再触发toggleRowSelection,ant design的api就没那么清晰了,言归正传 期望:Ant design table 单击行选中 勾选checkedbox 实现: 单选: onClickRow(record) { return { on: { click: () => { let keys = []; keys.push(record.id); th

  • ant design vue中日期选择框混合时间选择器的用法说明

    首先时间格式化用到moment方法,需要在页面中引入moment组件 import moment from 'moment' 结构代码: <a-date-picker style="width:100%" :getCalendarContainer="(triggerNode) => triggerNode.parentNode" format="YYYY-MM-DD HH:mm:ss" v-decorator="[ 'pu

  • 解决ant design vue中树形控件defaultExpandAll设置无效的问题

    页面步骤: 1.设置a-tree标签 2.默认的treeNodes值设置为空数组 3.在mounted组件加载的时候给treeNodes的值赋值 结果: 设置defaultExpandAll无效,并不能展开所有节点 原因: defaultExpandAll 仅在组件第一次渲染时有效,不仅仅tree组件,其它组件的defaultXXX值都是这个行为, 可以自行搜索受控组件/非受控组件的概念.如果你想异步获取数据后展开全部结点,可以使用非受控方式: https://codepen.io/lovefe

  • ant design vue中表格指定格式渲染方式

    注意点:定义的columns一定要写在data中,否则在加载过程中由于渲染顺序会导致其中的渲染函数无法识别 渲染方法1: 指定渲染函数: const columns = [ { title: '排名', dataIndex: 'key', customRender: renderContent // 渲染函数的规则 }, { title: '搜索关键词', dataIndex: 'keyword', customRender: (text, row, index) => { if (index

  • ant design vue datepicker日期选择器中文化操作

    按照ant design vue官方说明,使用日期选择器需要在入口文件(main.js)全局设置语言: // 默认语言为 en-US,如果你需要设置其他语言,推荐在入口文件全局设置 locale import moment from 'moment'; import 'moment/locale/zh-cn'; moment.locale('zh-cn'); <a-date-picker :defaultValue="moment('2015-01-01', 'YYYY-MM-DD')&q

  • ant design vue嵌套表格及表格内部编辑的用法说明

    实现效果: 因为pro手脚架中封装的s-table不支持expand和expandedRowsChange事件,无法实现根据展开节点获取其内部数据的需求,因此直接使用a-table组件 表格外层可以翻页,查询携带页码参数 <a-table size="default" rowKey="dict_id" //根据自己数据内部关键针设定 ref="table" @expandedRowsChange="expandedRowsChan

  • 解决ant design vue 表格a-table二次封装,slots渲染的问题

    目的就是对a-table进行二次封装,但是在如何显示a-table的slot时遇到了问题,原本想法是在a-table内把$slots都渲染,期望在使用该组件时能正确渲染,然而...并不会正确渲染 <template> <a-table bordered :scroll="{ x: scrollX, y: 600 }" v-bind="{...$attrs, ...$props, ...{dataSource: body, columns: header}}&

随机推荐