feat: menu items icon add arg
							parent
							
								
									760c4c2695
								
							
						
					
					
						commit
						eba8f6b960
					
				| 
						 | 
				
			
			@ -22,8 +22,9 @@ Horizontal top navigation menu.
 | 
			
		|||
<script lang="ts" setup>
 | 
			
		||||
import { h, ref } from 'vue';
 | 
			
		||||
import { MailOutlined, AppstoreOutlined, SettingOutlined } from '@ant-design/icons-vue';
 | 
			
		||||
import { MenuProps } from 'ant-design-vue';
 | 
			
		||||
const current = ref<string[]>(['mail']);
 | 
			
		||||
const items = ref([
 | 
			
		||||
const items = ref<MenuProps['items']>([
 | 
			
		||||
  {
 | 
			
		||||
    key: 'mail',
 | 
			
		||||
    icon: () => h(MailOutlined),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,14 +66,14 @@ More layouts with navigation: [Layout](/components/layout).
 | 
			
		|||
 | 
			
		||||
#### MenuItemType
 | 
			
		||||
 | 
			
		||||
| Param    | Description                          | Type    | Default value | Version |
 | 
			
		||||
| -------- | ------------------------------------ | ------- | ------------- | ------- |
 | 
			
		||||
| danger   | Display the danger style             | boolean | false         |         |
 | 
			
		||||
| disabled | Whether menu item is disabled        | boolean | false         |         |
 | 
			
		||||
| icon     | The icon of the menu item            | VueNode | -             |         |
 | 
			
		||||
| key      | Unique ID of the menu item           | string  | -             |         |
 | 
			
		||||
| label    | Menu label                           | VueNode | -             |         |
 | 
			
		||||
| title    | Set display title for collapsed item | string  | -             |         |
 | 
			
		||||
| Param | Description | Type | Default value | Version |
 | 
			
		||||
| --- | --- | --- | --- | --- |
 | 
			
		||||
| danger | Display the danger style | boolean | false |  |
 | 
			
		||||
| disabled | Whether menu item is disabled | boolean | false |  |
 | 
			
		||||
| icon | The icon of the menu item | VueNode \| (item: MenuItemType) => VNode | - |  |
 | 
			
		||||
| key | Unique ID of the menu item | string | - |  |
 | 
			
		||||
| label | Menu label | VueNode | - |  |
 | 
			
		||||
| title | Set display title for collapsed item | string | - |  |
 | 
			
		||||
 | 
			
		||||
#### SubMenuType
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ More layouts with navigation: [Layout](/components/layout).
 | 
			
		|||
| --- | --- | --- | --- | --- |
 | 
			
		||||
| children | Sub-menus or sub-menu items | [ItemType\[\]](#ItemType) | - |  |
 | 
			
		||||
| disabled | Whether sub-menu is disabled | boolean | false |  |
 | 
			
		||||
| icon | Icon of sub menu | VueNode\|()=>VueNode | - |  |
 | 
			
		||||
| icon | Icon of sub menu | VueNode \| (item: SubMenuType) => VueNode | - |  |
 | 
			
		||||
| key | Unique ID of the sub-menu | string | - |  |
 | 
			
		||||
| label | Menu label | VueNode | - |  |
 | 
			
		||||
| popupClassName | Sub-menu class name, not working when `mode="inline"` | string | - |  |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,14 +67,14 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*Vn4XSqJFAxcAAA
 | 
			
		|||
 | 
			
		||||
### MenuItemType
 | 
			
		||||
 | 
			
		||||
| 参数     | 说明                     | 类型                 | 默认值 | 版本 |
 | 
			
		||||
| -------- | ------------------------ | -------------------- | ------ | ---- |
 | 
			
		||||
| danger   | 展示错误状态样式         | boolean              | false  |      |
 | 
			
		||||
| disabled | 是否禁用                 | boolean              | false  |      |
 | 
			
		||||
| icon     | 菜单图标                 | VueNode\|()=>VueNode | -      |      |
 | 
			
		||||
| key      | item 的唯一标志          | string               | -      |      |
 | 
			
		||||
| label    | 菜单项标题               | VueNode              | -      |      |
 | 
			
		||||
| title    | 设置收缩时展示的悬浮标题 | string               | -      |      |
 | 
			
		||||
| 参数     | 说明                     | 类型                                   | 默认值 | 版本 |
 | 
			
		||||
| -------- | ------------------------ | -------------------------------------- | ------ | ---- |
 | 
			
		||||
| danger   | 展示错误状态样式         | boolean                                | false  |      |
 | 
			
		||||
| disabled | 是否禁用                 | boolean                                | false  |      |
 | 
			
		||||
| icon     | 菜单图标                 | VueNode\|(item: MenuItemType)=>VueNode | -      |      |
 | 
			
		||||
| key      | item 的唯一标志          | string                                 | -      |      |
 | 
			
		||||
| label    | 菜单项标题               | VueNode                                | -      |      |
 | 
			
		||||
| title    | 设置收缩时展示的悬浮标题 | string                                 | -      |      |
 | 
			
		||||
 | 
			
		||||
#### SubMenuType
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*Vn4XSqJFAxcAAA
 | 
			
		|||
| --- | --- | --- | --- | --- |
 | 
			
		||||
| children | 子菜单的菜单项 | [ItemType\[\]](#ItemType) | - |  |
 | 
			
		||||
| disabled | 是否禁用 | boolean | false |  |
 | 
			
		||||
| icon | 菜单图标 | VueNode\|()=>VueNode | - |  |
 | 
			
		||||
| icon | 菜单图标 | VueNode\|(item: SubMenuType)=>VueNode | - |  |
 | 
			
		||||
| key | 唯一标志 | string | - |  |
 | 
			
		||||
| label | 菜单项标题 | VueNode | - |  |
 | 
			
		||||
| popupClassName | 子菜单样式,`mode="inline"` 时无效 | string | - |  |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,13 @@ import { computed, defineComponent } from 'vue';
 | 
			
		|||
import PropTypes from '../../_util/vue-types';
 | 
			
		||||
import { useInjectMenu } from './hooks/useMenuContext';
 | 
			
		||||
import { useMeasure } from './hooks/useKeyPath';
 | 
			
		||||
import type { ItemType } from './interface';
 | 
			
		||||
import { objectType } from '../../_util/type';
 | 
			
		||||
 | 
			
		||||
export const menuItemGroupProps = () => ({
 | 
			
		||||
  title: PropTypes.any,
 | 
			
		||||
  // Internal user prop
 | 
			
		||||
  originItemValue: objectType<ItemType>(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export type MenuItemGroupProps = Partial<ExtractPropTypes<ReturnType<typeof menuItemGroupProps>>>;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import { flattenChildren, getPropsSlot, isValidElement } from '../../_util/props-util';
 | 
			
		||||
import { flattenChildren, isValidElement } from '../../_util/props-util';
 | 
			
		||||
import PropTypes from '../../_util/vue-types';
 | 
			
		||||
import type { ExtractPropTypes, PropType } from 'vue';
 | 
			
		||||
import {
 | 
			
		||||
| 
						 | 
				
			
			@ -13,12 +13,13 @@ import { useInjectKeyPath, useMeasure } from './hooks/useKeyPath';
 | 
			
		|||
import { useInjectFirstLevel, useInjectMenu } from './hooks/useMenuContext';
 | 
			
		||||
import { cloneElement } from '../../_util/vnode';
 | 
			
		||||
import Tooltip from '../../tooltip';
 | 
			
		||||
import type { MenuInfo } from './interface';
 | 
			
		||||
import type { ItemType, MenuInfo } from './interface';
 | 
			
		||||
import KeyCode from '../../_util/KeyCode';
 | 
			
		||||
import useDirectionStyle from './hooks/useDirectionStyle';
 | 
			
		||||
import Overflow from '../../vc-overflow';
 | 
			
		||||
import devWarning from '../../vc-util/devWarning';
 | 
			
		||||
import type { MouseEventHandler } from '../../_util/EventInterface';
 | 
			
		||||
import { objectType } from '../../_util/type';
 | 
			
		||||
 | 
			
		||||
let indexGuid = 0;
 | 
			
		||||
export const menuItemProps = () => ({
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +34,8 @@ export const menuItemProps = () => ({
 | 
			
		|||
  onClick: Function as PropType<MouseEventHandler>,
 | 
			
		||||
  onKeydown: Function as PropType<MouseEventHandler>,
 | 
			
		||||
  onFocus: Function as PropType<MouseEventHandler>,
 | 
			
		||||
  // Internal user prop
 | 
			
		||||
  originItemValue: objectType<ItemType>(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export type MenuItemProps = Partial<ExtractPropTypes<ReturnType<typeof menuItemProps>>>;
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +218,7 @@ export default defineComponent({
 | 
			
		|||
        optionRoleProps['aria-selected'] = selected.value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const icon = getPropsSlot(slots, props, 'icon');
 | 
			
		||||
      const icon = props.icon ?? slots.icon?.(props);
 | 
			
		||||
      return (
 | 
			
		||||
        <Tooltip
 | 
			
		||||
          {...tooltipProps}
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +251,7 @@ export default defineComponent({
 | 
			
		|||
            title={typeof title === 'string' ? title : undefined}
 | 
			
		||||
          >
 | 
			
		||||
            {cloneElement(
 | 
			
		||||
              typeof icon === 'function' ? icon() : icon,
 | 
			
		||||
              typeof icon === 'function' ? icon(props.originItemValue) : icon,
 | 
			
		||||
              {
 | 
			
		||||
                class: `${prefixCls.value}-item-icon`,
 | 
			
		||||
              },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,8 @@ import devWarning from '../../vc-util/devWarning';
 | 
			
		|||
import isValid from '../../_util/isValid';
 | 
			
		||||
import type { MouseEventHandler } from '../../_util/EventInterface';
 | 
			
		||||
import type { Key } from '../../_util/type';
 | 
			
		||||
import type { MenuTheme } from './interface';
 | 
			
		||||
import { objectType } from '../../_util/type';
 | 
			
		||||
import type { ItemType, MenuTheme } from './interface';
 | 
			
		||||
 | 
			
		||||
let indexGuid = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +47,9 @@ export const subMenuProps = () => ({
 | 
			
		|||
  onMouseenter: Function as PropType<MouseEventHandler>,
 | 
			
		||||
  onMouseleave: Function as PropType<MouseEventHandler>,
 | 
			
		||||
  onTitleClick: Function as PropType<(e: MouseEvent, key: Key) => void>,
 | 
			
		||||
 | 
			
		||||
  // Internal user prop
 | 
			
		||||
  originItemValue: objectType<ItemType>(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export type SubMenuProps = Partial<ExtractPropTypes<ReturnType<typeof subMenuProps>>>;
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +228,7 @@ export default defineComponent({
 | 
			
		|||
      return (
 | 
			
		||||
        <>
 | 
			
		||||
          {cloneElement(
 | 
			
		||||
            typeof icon === 'function' ? icon() : icon,
 | 
			
		||||
            typeof icon === 'function' ? icon(props.originItemValue) : icon,
 | 
			
		||||
            {
 | 
			
		||||
              class: `${prefixCls.value}-item-icon`,
 | 
			
		||||
            },
 | 
			
		||||
| 
						 | 
				
			
			@ -247,7 +251,7 @@ export default defineComponent({
 | 
			
		|||
    );
 | 
			
		||||
    const baseTitleNode = () => {
 | 
			
		||||
      const subMenuPrefixClsValue = subMenuPrefixCls.value;
 | 
			
		||||
      const icon = getPropsSlot(slots, props, 'icon');
 | 
			
		||||
      const icon = props.icon ?? slots.icon?.(props);
 | 
			
		||||
      const expandIcon = props.expandIcon || slots.expandIcon || menuExpandIcon.value;
 | 
			
		||||
      const title = renderTitle(getPropsSlot(slots, props, 'title'), icon);
 | 
			
		||||
      return (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,19 +9,19 @@ import ItemGroup from '../ItemGroup';
 | 
			
		|||
import MenuDivider from '../Divider';
 | 
			
		||||
import MenuItem from '../MenuItem';
 | 
			
		||||
import type { Key } from '../../../_util/type';
 | 
			
		||||
import type { VNode } from 'vue';
 | 
			
		||||
import { ref, shallowRef, watch } from 'vue';
 | 
			
		||||
import type { MenuProps } from '../Menu';
 | 
			
		||||
import type { StoreMenuInfo } from './useMenuContext';
 | 
			
		||||
 | 
			
		||||
export interface MenuItemType extends VcMenuItemType {
 | 
			
		||||
  danger?: boolean;
 | 
			
		||||
  icon?: any;
 | 
			
		||||
  icon?: VNode | ((item: MenuItemType) => VNode);
 | 
			
		||||
  title?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface SubMenuType extends Omit<VcSubMenuType, 'children'> {
 | 
			
		||||
  icon?: any;
 | 
			
		||||
  theme?: 'dark' | 'light';
 | 
			
		||||
  icon?: VNode | ((item: SubMenuType) => VNode);
 | 
			
		||||
  children: ItemType[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ function convertItemsToNodes(
 | 
			
		|||
            const childrenNodes = convertItemsToNodes(children, store, parentMenuInfo);
 | 
			
		||||
            // Group
 | 
			
		||||
            return (
 | 
			
		||||
              <ItemGroup key={mergedKey} {...restProps} title={label}>
 | 
			
		||||
              <ItemGroup key={mergedKey} {...restProps} title={label} originItemValue={opt}>
 | 
			
		||||
                {childrenNodes}
 | 
			
		||||
              </ItemGroup>
 | 
			
		||||
            );
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ function convertItemsToNodes(
 | 
			
		|||
            parentKeys: [].concat(parentKeys, mergedKey),
 | 
			
		||||
          });
 | 
			
		||||
          return (
 | 
			
		||||
            <SubMenu key={mergedKey} {...restProps} title={label}>
 | 
			
		||||
            <SubMenu key={mergedKey} {...restProps} title={label} originItemValue={opt}>
 | 
			
		||||
              {childrenNodes}
 | 
			
		||||
            </SubMenu>
 | 
			
		||||
          );
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +97,7 @@ function convertItemsToNodes(
 | 
			
		|||
        menuInfo.isLeaf = true;
 | 
			
		||||
        store.set(mergedKey, menuInfo);
 | 
			
		||||
        return (
 | 
			
		||||
          <MenuItem key={mergedKey} {...restProps}>
 | 
			
		||||
          <MenuItem key={mergedKey} {...restProps} originItemValue={opt}>
 | 
			
		||||
            {label}
 | 
			
		||||
          </MenuItem>
 | 
			
		||||
        );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue