快速开始
本节以开发一个Card组件为例说明使用方法:
- 组件有一个
title属性,用于显示标题 footer属性,用于显示底部内容children属性作为卡片的内容区。
第1步:创建样式组件
flexstyled提供styled高阶函数用来创建一个支持CSS-IN-JS样式的组件。
tsx
import { styled } from "flexstyled"
export type CardProps = React.PropsWithChildren<{
title:string
footer?:string
}>
export const Card = styled<CardProps>((props,{className})=>{
const { title,children,footer} =props
return (
<div className={className}>
<div>
{title}
</div>
<div>{children}</div>
<div>{footer}</div>
</div>
)
},{
position:"relative",
width:"100%",
border:"1px solid #ccc",
borderRadius:"4px"
})- 以上代码将创建一个
Card组件,为样式生成一个样式类(类名称是随机生成的)并插入到head标签中。 - 然后将
className属性传递给组件,组件将使用这个类名来应用样式。
你可以在head发现一个类似这样的CSS样式,其中的类名和style.id均是自动生成的。
html
<style id="6rxqfu">
.sw6y3s4{
position:relative;
width:100%;
border:1px solid #ccc;
border-radius:4px;
}
</style>TIP
注:类名和style.id也可以通过options参数来指定。
第2步:嵌套样式
接下来我们为Card组件的header、body和footer添加样式,并且使用嵌套样式。
tsx
export const Card = styled<CardProps>((props,{className})=>{
const { title,children,footer} =props
return (
<div className={className}>
<div className="header">
{title}
</div>
<div className="body">{children}</div>
<div className="footer">{footer}</div>
</div>
)
},{
position:"relative",
width:"100%",
border:"1px solid #ccc",
borderRadius:"4px",
"& > .header":{
padding:"10px",
borderBottom:"1px solid #ccc"
},
"& > .body":{
padding:"10px",
backgroundColor:'#f9f9f9'
},
"& > .footer":{
padding:"10px",
borderTop:"1px solid #ccc"
}
})可以看到flexstyled支持类似less/sass/scss的嵌套样式的写法来为组件的子元素指定嵌套样式。
TIP
注:嵌套样式的写法是通过&符号来指定当前元素的样式。原则上支持所有的css选择器。您可以将在less/sass/scss中的实践直接应用到flexstyled中。
第3步:动态样式
接下来我们为Card组件提供一个headerBgColor属性,用来配置卡片头部的背景色。
tsx
export type CardProps = React.PropsWithChildren<{
headerBgColor?:string
title:string
footer?:string
}>
export const Card = styled<CardProps>((props,{className,getStyle})=>{
const { title,children,footer} =props
return (
<div className={className} style={getStyle()}>
<div className="header">
{title}
</div>
<div className="body">{children}</div>
<div className="footer">{footer}</div>
</div>
)
},{
position:"relative",
width:"100%",
border:"1px solid #ccc",
borderRadius:"4px",
"& > .header":{
padding:"10px",
borderBottom:"1px solid #ccc",
backgroundColor:(props)=>props.headerBgColor
},
"& > .body":{
padding:"10px",
backgroundColor:'#f9f9f9'
},
"& > .footer":{
padding:"10px",
borderTop:"1px solid #ccc"
}
})- 首先可以在样式中使用
(props)=>props.headerBgColor来动态获取headerBgColor属性。 - 接着需要在根元素上使用
style={getStyle()}来注入动态样式,getStyle返回的是一个样式对象。
提示
由于上例中我们使用了props=>props.headerBgColor来动态获取headerBgColor属性,所以需要通过 getStyle函数来注入动态样式。如果样式中没有使用到任何CSS变量或动态样式,那么可以省略style={getStyle()}。
小结
- 使用
styled高阶函数创建一个支持CSS-IN-JS样式的组件,组件的CSS将被自动插入到head标签中。 - 支持类似
less/sass/scss的方式来为组件的子元素指定样式。 - 所有的样式均支持通过
(props)=>{}来提供组件的动态属性值。
更完整的卡片组件示例可以参考这里。