使用 props 设置 '&:hover' 背景色
Posted
技术标签:
【中文标题】使用 props 设置 \'&:hover\' 背景色【英文标题】:Using props to set '&:hover' background-color使用 props 设置 '&:hover' 背景色 【发布时间】:2019-07-27 05:54:00 【问题描述】:我正在包装 MUI 的 Chip
组件,以便我可以为 colors
属性传递除“主要”和“次要”之外的值。如果芯片是可点击的,我还想保持悬停效果,以便当光标悬停在芯片上时,芯片会转换为不同的颜色。颜色作为道具传入,因此设置backgroundColor
和color
很容易:
<Chip
style=
backgroundColor: props.backgroundColor,
color: props.color
/>
但是,由于我还想将悬停颜色作为道具传递,我需要执行以下操作:
<Chip
style=
backgroundColor: props.backgroundColor,
color: props.color,
'&:hover':
backgroundColor: props.hoverBackgroundColor,
color: props.hoverColor
/>
但是,&:hover
(据我所知)不能在 style
属性内使用。通常,&:hover
将在传递给withStyles
的样式对象内使用,但我无法从那里访问道具。有什么建议吗?
【问题讨论】:
【参考方案1】:在MUI v5中,您可以使用sx
prop 来设置:hover
等伪类的样式:
<Chip
label="Chip"
onClick=() =>
sx=
':hover':
bgcolor: 'red',
,
/>
如果你想创建一个可重用的样式组件,另一种选择是styled()
:
const options =
shouldForwardProp: (prop) => prop !== 'hoverBgColor',
;
const StyledChip = styled(
Chip,
options,
)(( hoverBgColor ) => (
':hover':
backgroundColor: hoverBgColor,
,
));
<StyledChip label="Chip" onClick=() => hoverBgColor="red" />
【讨论】:
【参考方案2】:您可以通过创建自己的自定义芯片组件来实现这一点。为了能够使用道具来控制样式,可以使用makeStyles
。 makeStyles
函数返回一个钩子,该钩子可以接受一个对象参数,以便为您的样式提供变量。
这是一个可能的 CustomChip 实现:
import React from "react";
import Chip from "@material-ui/core/Chip";
import makeStyles from "@material-ui/core/styles";
import emphasize from "@material-ui/core/styles/colorManipulator";
const useChipStyles = makeStyles(
chip:
color: ( color ) => color,
backgroundColor: ( backgroundColor ) => backgroundColor,
"&:hover, &:focus":
backgroundColor: ( hoverBackgroundColor, backgroundColor ) =>
hoverBackgroundColor
? hoverBackgroundColor
: emphasize(backgroundColor, 0.08)
,
"&:active":
backgroundColor: ( hoverBackgroundColor, backgroundColor ) =>
emphasize(
hoverBackgroundColor ? hoverBackgroundColor : backgroundColor,
0.12
)
);
const CustomChip = (
color,
backgroundColor,
hoverBackgroundColor,
...rest
) =>
const classes = useChipStyles(
color,
backgroundColor,
hoverBackgroundColor
);
return <Chip className=classes.chip ...rest />;
;
export default CustomChip;
样式方法(包括使用emphasize
函数生成悬停颜色和活动颜色)基于Chip
内部使用的方法。
然后可以这样使用:
<CustomChip
label="Custom Chip 1"
color="green"
backgroundColor="#ccf"
onClick=() =>
console.log("clicked 1");
/>
<CustomChip
label="Custom Chip 2"
color="#f0f"
backgroundColor="#fcc"
hoverBackgroundColor="#afa"
onClick=() =>
console.log("clicked 2");
/>
这是一个演示这个的 CodeSandbox:
这是该示例的 Material-UI v5 版本:
import Chip from "@material-ui/core/Chip";
import styled from "@material-ui/core/styles";
import emphasize from "@material-ui/core/styles";
import shouldForwardProp from "@material-ui/system";
function customShouldForwardProp(prop)
return (
prop !== "color" &&
prop !== "backgroundColor" &&
prop !== "hoverBackgroundColor" &&
shouldForwardProp(prop)
);
const CustomChip = styled(Chip, shouldForwardProp: customShouldForwardProp )(
( color, backgroundColor, hoverBackgroundColor ) => (
color: color,
backgroundColor: backgroundColor,
"&:hover, &:focus":
backgroundColor: hoverBackgroundColor
? hoverBackgroundColor
: emphasize(backgroundColor, 0.08)
,
"&:active":
backgroundColor: emphasize(
hoverBackgroundColor ? hoverBackgroundColor : backgroundColor,
0.12
)
)
);
export default CustomChip;
【讨论】:
这似乎工作得很好。不幸的是,我使用的是不支持钩子的 React 版本。希望我们能很快到达那里。同时,我想出了一个解决方案,它使用 HOC 将使用 props 的样式注入到组件中。这是CodeSandbox Material-UI v4 将需要 hooks 支持,因此为了不断获得 Material-UI 的进一步增强,您肯定希望升级 React。只要您已经在使用 React 16 而不是某个早期版本,它应该是一个非常轻松的升级。 @RyanCogswell 为什么又从系统包中调用shouldForwardProp
? docs 中的示例没有做到这一点,无论是否在第二个 shouldForwardProp
的情况下在代码盒中玩耍时,它对我没有任何影响。
@NearHuscarl 我想我包含了它,因为在查看源代码时,当您指定自定义 shouldForwardProp
时,它不会添加到默认值 - 它会替换它。假设默认实现至少在某些情况下会产生影响,我将其包括在内,但我还没有发现它似乎会产生影响的情况。文档中的示例确实包含默认实现的一部分(检查sx
),但我不清楚在什么情况下会产生影响。
it isn't additive to the default
这就是为什么它让我感到困惑,看起来你的代码是基于源代码的方式,因为自定义shouldForwardProp
overrides the original one from the system completely,它不使用createChainedFunction
合并多个功能。在阅读源代码时,我可能在某处错过了一些额外的魔法。以上是关于使用 props 设置 '&:hover' 背景色的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在 html 电子邮件中的“a:hover”上的 href 链接上设置内联样式?
Vue.js + Typescript:如何将@Prop 类型设置为字符串数组?