Skip to content

快速开始

本节以开发一个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组件的headerbodyfooter添加样式,并且使用嵌套样式

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)=>{}来提供组件的动态属性值。

更完整的卡片组件示例可以参考这里