You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向MUI styled Menu传递props实现条件样式效果?

解决方案

MUI 的 styled 工具支持透传自定义属性到样式回调函数,你只需要显式声明要传入的自定义属性,就可以在样式定义中直接访问做条件判断,不需要把样式定义迁移到组件内部,具体修改如下:

  • 给 StyledMenu 扩展自定义属性声明,同时在样式回调中接收该属性用于条件判断
  • 在 Expandable 组件调用 StyledMenu 时,把当前的 type 值作为自定义属性传入
  • 修正原有代码的语法错误和无效属性值

修改后的完整代码:

import { styled, alpha } from '@mui/material/styles';
import Menu, { MenuProps } from '@mui/material/Menu';
import Box from '@mui/material/Box';
import React, { useContext } from 'react';

// 给styled泛型扩展自定义menuType属性,避免TS类型报错,纯JS环境可删除泛型声明
const StyledMenu = styled((props: MenuProps & { menuType?: string }) => (
  <Menu
    elevation={0}
    anchorOrigin={{
      vertical: 'bottom',
      horizontal: 200,
    }}
    transformOrigin={{
      vertical: 'top',
      horizontal: 'right',
    }}
    {...props}
  />
))(({ theme, menuType }) => ({
  // 修正原rgba无效值,颜色通道最大值为255
  backgroundColor: 'rgba(255, 255, 255, 0.455)',
  backdropFilter: 'blur(1px)',
  '& .MuiPaper-root': {
    borderRadius: 3,
    // 直接在属性值位置做条件判断即可
    minWidth: menuType === 'Type' ? 1360 : 250,
    marginTop: theme.spacing(1),
    color: theme.palette.mode === 'light' ? 'rgb(55, 65, 81)' : theme.palette.grey[300],
    boxShadow: 'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px',
    '& .MuiMenu-list': {
      padding: '4px 0',
    },
    '& .MuiMenuItem-root': {
      '& .MuiSvgIcon-root': {
        fontSize: 18,
        color: theme.palette.text.secondary,
        marginRight: theme.spacing(1.5),
      },
      '&:active': {
        backgroundColor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
      },
    },
  },
}));

interface Props {
  source: any;
  type: string;
  date: string;
  icon: React.ReactNode;
}

// 请替换为你的实际上下文定义
const movementsContext = React.createContext<any>(null);

export const Expandable: React.FC<Props> = ({ source, type, date, icon }) => {
  const context = useContext(movementsContext);
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
  const open = Boolean(anchorEl);
  const handleClick = (event: React.MouseEvent<HTMLElement>) => {
    setAnchorEl(event.currentTarget);
  };
  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <Box style={{ margin: 'auto', display: 'flex', justifyContent: 'center' }}>
      {/* 把当前type作为menuType属性传给StyledMenu */}
      <StyledMenu
        id='demo-customized-menu'
        menuType={type}
        MenuListProps={{
          'aria-labelledby': 'demo-customized-button',
        }}
        anchorEl={anchorEl}
        open={open}
        onClose={handleClose}
      >
        {/* 此处放置你的MenuItem子项 */}
      </StyledMenu>
    </Box>
  );
};

内容的提问来源于stack exchange,提问作者Richardson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:06:00