styled-components
是一个CSS-in-JS 库,用于在 React 框架中编写 CSS 样式。
1.安装依赖包、vscode插件:Simple React Snippets(有提示)
npm install styled-components
#或者
yarn add styled-components
2.创建一个style.js的样式组件,写基本样式
语法格式:export const TabsWrapper = styled.div` ` 把一个div变成了一个名为TabsDiv的组件,然后在 ` `中定义样式。直接写属性的样式就是div的样式。通过. 类选择器写的就是TabsDiv子代元素的样式,如:
javascript
import styled, { keyframes,css } from 'styled-components';
export const TabsdDiv = styled.div`
height: 72px;
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column;
padding: 10px 0;
${props=>props.active && css`
border-bottom: 2px solid #000000;
`}
.img{
height: 24px;
width: 24px;
}
&:hover {
border-bottom: 2px solid #eeeeea
}
`
3.导入到react组件中去使用 将StyledDiv导入直接作为组件使用,如:
javascript
import React, { memo, useState } from 'react'
import {TabsdDiv} from './style'
import { StyledDiv } from '@/base-ui/style';
<StyledDiv className="tab-div" width="100%" center justifyContent="space-between" >
{children.map((tab, index) => (
<TabsdDiv key={index} active={index == activeTab} onClick={() => handleTabClick(index)}>
<img src={fz} alt="" className='img' />
{tab.props.label}
</TabsdDiv>
))}
</StyledDiv>
4.进阶用法一:通过样式组件传参,动态控制样式,如:
javascript
${props=>props.active && css`
border-bottom: 2px solid #000000;
`}
样式组件内部通过props接受一个 active的属性 props.active的值为真就执行后面的样式,注意:css是一个函数需要导入
5.进阶用法二:根据动态样式控制 配置一个公用的万能div组件,使用的时候只需要在组件中传递参数就能达到想要的样式,如:(StyleDiv为一个基础div)
javascript
import styled, { keyframes,css } from 'styled-components';
export const StyledDiv = styled.div`
width: ${props=>props.width};
height: ${props=>props.height};
border-radius: ${props=>props.radius};
box-shadow:${props=>props.shadow} ;
flex: ${props=>props.flexValue};
background-color:${props=>props.bgColor};
${props => props.flex && css`
display: flex;
justify-content: ${props.justifyContent || 'flex-start'};
align-items: ${props.alignItems || 'center'};
flex: ${props.flexValue};
`}
${props => props.center && css`
display: flex;
justify-content: ${props.justifyContent || 'center'};
align-items: ${props.alignItems || 'center'};
flex: ${props.flexValue};
`}
${props => props.grid && css`
display: grid;
grid-template-columns: ${props => props.gridTemplateColumns || '1fr'};
grid-template-rows: ${props => props.gridTemplateRows || 'auto'};
gap: ${props => props.gap || '0'};
`}
${props => props.text && css`
color: ${props.textColor || 'black'};
font-size: ${props.textSize || '16px'};
font-weight: ${props.fontWeight || 'normal'};
text-align: ${props.textAlign || 'left'};
line-height: ${props.lineHeight || '1.5'};
`}
${props => props.background && css`
background-color: ${props.bg || 'transparent'};
`}
${props => props.padding && css`
padding: ${props.pd};
padding-left: ${props.pdl};
padding-top: ${props.pdt};
padding-right: ${props.pdr};
padding-bottom: ${props.pdb};
`}
${props => props.margin && css`
margin: ${props.mg};
margin-left: ${props.mgl};
margin-bottom: ${props.mgb};
margin-right: ${props.mgr};
margin-top: ${props.mgt};
`}
${props => props.border && css`
border: ${props.bd};
border-bottom: ${props.bdb};
border-top: ${props.bdt};
border-left: ${props.bdl};
border-right: ${props.bdr};
`}
`;
基础div组件使用:(通过在StyledDiv上设置属性即可写出相应的样式 )
javascript
import React, { memo } from 'react'
import InconSearch from '../../../assets/svg/icon_search'
import { StyledDiv } from '@/base-ui/style';
const CenterLow = memo(function index() {
return (
<StyledDiv width='293px' height='46px' flex justifyContent='space-between' shadow="0px 0px 10px rgba(0, 0, 0, 0.1)" radius="20px" text textSize='14px' padding pd="0 10px 0 10px">
<StyledDiv flexValue='1' border bdr="1px solid #eeeeeeea" center>任何地方</StyledDiv>
<StyledDiv flexValue='1' border bdr="1px solid #eeeeeeea" center>任意一周</StyledDiv>
<StyledDiv flexValue='1' center>添加人数</StyledDiv>
<StyledDiv radius="50%" bgColor="#ff385c" width='32px' height="32px" center><InconSearch/></StyledDiv>
</StyledDiv>
)
})
export default CenterLow
6.进阶用法三:通过关键帧写动画;导入keyframes函数 定义关键帧变量
javascript
import styled, { keyframes,css } from 'styled-components';
export const CarouselDiv = styled.div`
width: 400px;
height: 400px;
position: relative;
background-color: yellow;
overflow: hidden; /* 控制超出父容器部分隐藏 */
margin-left: 500px;
.item1 {
display: ${({ active }) => active == 0 ? 'flex' : 'none'};
background-color: red;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
animation: ${({ active,button }) => active === 0 && button==='right' ? css`${enterAnimation} 0.4s linear`:css`${leaveAnimation} 0.4s linear`}
}
.item2 {
display: ${({ active }) => active == 1 ? 'flex' : 'none'};
background-color: blue;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
animation: ${({ active,button }) => active === 1 && button==='right' ? css`${enterAnimation} 0.4s linear`:css`${leaveAnimation} 0.4s linear`}
}
.item3 {
display: ${({ active }) => active == 2 ? 'flex' : 'none'};
background-color: green;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
animation: ${({ active,button }) => active === 2 && button==='right' ? css`${enterAnimation} 0.4s linear`:css`${leaveAnimation} 0.4s linear`}
}
.leftButton {
position: absolute;
top: 50%;
left: 0px;
}
.rightButton {
position: absolute;
top: 50%;
right: 0px; /* 调整右侧按钮的定位 */
}
`;
// 定义 enter 动画的关键帧
const enterAnimation = keyframes`
0% {
opacity: 0;
transform: translateX(0%);
}
50% {
opacity: 1;
}
100% {
transform: translateX(100%);
}
`;
// 定义 leave 动画的关键帧
const leaveAnimation = keyframes`
0% {
opacity: 1;
transform: translateX(100%);
}
50% {
opacity: 0;
}
100% {
transform: translateX(0%);
}
`;