样式化组件的多个道具选项
Posted
技术标签:
【中文标题】样式化组件的多个道具选项【英文标题】:Multiple Props Options for Styled Components 【发布时间】:2019-09-26 14:17:49 【问题描述】:我有一个使用样式化组件创建的导航栏组件。我想创建一些改变背景颜色和/或文本颜色的道具。
例如:<Navbar dark>
应具有以下 CSS:
background: #454545;
color: #fafafa;
而<Navbar light>
应该相反:
background: #fafafa;
color: #454545;
但是,如果两个道具都没有使用,那么我想要一个默认的背景和文本颜色——比如说(出于演示目的),如下所示:
background: #eee;
color: #333;
现在,我的问题是如何在 Styled Components 中进行设置。
我可以做到以下几点:
background: $props => props.dark ? #454545 : '#eee'
background: $props => props.dark ? #fafafa : '#eee'
background: #eee;
颜色也类似。
但这是多余的,不是很优雅。我想要某种 if/else 语句:
background: $ props =>
if (props.dark) #454545
elseif (props.light) #fafafa
else #eee
但我不知道如何在 Styled Components 中设置类似的内容。
有什么建议吗?
提前致谢。
【问题讨论】:
【参考方案1】:保持传入的prop
名称相同。然后您可以使用switch/case
语句。例如,传入 color
属性并将其用作 type
以匹配 case
。
工作示例:
例如:
<Button color="primary">Example</Button>
组件/按钮
import styled from "styled-components";
const handleColorType = color =>
switch (color)
case "primary":
return "#03a9f3";
case "danger":
return "#f56342";
default:
return "#fff";
;
const Button = styled.button`
display: block;
cursor: pointer;
border: 0;
margin: 5px 0;
background: #000;
font-size: 20px;
color: $( color ) => handleColorType(color);
&:focus
outline: 0;
`;
export default Button;
如果您有多个属性(例如 color
和 background
对),则使用与上述相同的概念,更改 handleColorType
以返回带有属性的 string
并调用 handleColorType
函数没有样式属性。
例如:
<MultiButton color="primary">Example</MultiButton>
组件/多按钮
import styled from "styled-components";
const handleColorType = color =>
switch (color)
case "primary":
return "color: #03a9f3; background: #000;";
case "danger":
return "color: #fff; background: #f56342;";
default:
return "color: #000; background: #eee;";
;
const MultiButton = styled.button`
display: block;
margin: 5px 0;
cursor: pointer;
border: 0;
font-size: 20px;
$( color ) => handleColorType(color);
&:focus
outline: 0;
`;
export default MultiButton;
【讨论】:
这非常漂亮和优雅(我肯定有时会使用它)。但是,当我 不 想要将值传递给道具时,我也想要一个解决方案(例如我上面给出的深色和浅色示例)。我可以修改您的解决方案,使用 if/else 语句来检查是否设置了道具 - 即类似if (props.dark) return 'background-color: #454545; color: #fafafa' elseif...
。这行得通吗?
或者,或者--是否可以将 switch 与道具一起使用,然后检查不同类型的道具。像这样的东西:switch (props) case props.dark...
?我正在尝试使其正常工作,但出现错误。有什么想法吗?
如果所有情况都不匹配,switch/case
的 default
会返回一些东西(或者可以是什么)。请参阅代码框示例。此外,再次保持相同的道具名称。在 props 中使用“dark”和“light”将迫使您使用重度嵌套的 if/else
语句。
但是,如果这是您绝对想要的,那么是的,您只需要添加一个 return
语句即可。
只是喜欢这种方法。一位前同事向我介绍了这一点,它比我使用的任何其他方法都优雅得多。【参考方案2】:
这是我最终使用的解决方案:
export const Navbar = styled.nav`
width: 100%;
... // rest of the regular CSS code
$props =>
if (props.dark)
return `
background: $colors.dark;
color: $colors.light;
`
else if (props.light)
return `
background: $colors.light;
color: $colors.dark;
`
else
return `
background: $colors.light;
color: $colors.dark;
`
`
【讨论】:
这是我一直在寻找的。span> 【参考方案3】:你也可以这样做:
const colorType=
dark: '#454545',
light: '#0a0a0a',
normal: '#dedede'
;
export const Navbar= styled.nav`
background: $(color) => colorType[color] || `$color`;
`;
你在这里:
<Navbar color="primary" />
<Navbar color="#FFFFFF" />
【讨论】:
【参考方案4】:更优雅(我猜)和现代的东西是解构道具和使用 switch 语句的组合,例如:
const Button = styled.button`
$(primary, secondary) =>
switch(true)
case primary:
return `background-color : green`
case secondary:
return `background-color : red`
`
【讨论】:
【参考方案5】:样式化组件还接受一个函数,您可以在其中读取道具。此外,如果您选择传递主题道具,您还可以为您的主题定义一个对象。
const themes =
dark: css `
background: $colors.dark;
color: $colors.light;
`,
light: css`
background: $colors.light;
color: $colors.dark;
`
export const Navbar = styled.nav((theme)=>`
width: 100%;
background: $colors.light;
color: $colors.dark;
... // rest of the css
$theme?themes[theme]:''
`)
<Navbar theme="dark" />
【讨论】:
【参考方案6】:使用Styled-tools的解决方案
根据您的具体情况
因为你只有两个主题,一个默认是light
,一个是dark
,你可以切换到一个,你只需要检查它是否是暗模式。
import ifProp from "styled-tools";
export const Navbar = styled.nav`
$ifProp("dark",
css`
background: $colors.dark;
color: $colors.light;
`,
css`
background: $colors.light;
color: $colors.dark;
`,
)
`;
并使用<Navbar $dark=isDarkMode />
进行渲染
更通用的解决方案
当然,您仍然希望使用深色/浅色等主题方法。设置变体会使事情变得更容易。例如,您可以在单独的枚举中跟踪您想要的不同主题。像这样:
enum Themes
DARK = "dark",
LIGHT = "light",
您可以在稍后的样式中指定:
import switchProp from "styled-tools";
export const Navbar = styled.nav`
$switchProp(
dark: css`
background: $colors.dark;
color: $colors.light;
`,
light: css`
background: $colors.light;
color: $colors.dark;
`,
)
`;
然后渲染<Navbar variant=Theme.LIGHT />
或<Navbar variant=Theme.DARK />
参考文献
transient props switch prop【讨论】:
【参考方案7】:怎么样:
const StyledButton = styled.button`
padding: 8px 16px;
border-radius: $props => props.rounded ? '10px' : '0px';
$props =>
switch (props.type)
case 'primary':
return `
background-color : #000;
color: #fff;
border: 1px solid #000000;
`;
case 'secondary':
return `
background-color : #DEDEDE;
border: 1px solid #999;
`;
`;
【讨论】:
以上是关于样式化组件的多个道具选项的主要内容,如果未能解决你的问题,请参考以下文章