React学习: styled-components
常用用法,记录
$ 开头的变量
如果不用这个,就会出现 bgColor 等出现在 div上,最终报 warning
import styled from 'styled-components';
import cx from 'classnames';
const RANK_LIST = [
{ icon: '/static/images/main/consultant/first.png', color: '#CD72FB', bgColor: '#F4DFFD' },
{ icon: '/static/images/main/consultant/second.png', color: '#2B94FF', bgColor: '#D7ECFE' },
{ icon: '/static/images/main/consultant/third.png', color: '#FFA600', bgColor: '#FFFBE8' },
{ icon: '/static/images/main/consultant/fourth.png', color: '#919191', bgColor: '#C0C0C0' },
{ icon: '/static/images/main/consultant/fifth.png', color: '#EB6D2B', bgColor: '#FFD9C3' }
];
const Container = styled.div<{ $color: string; $bgColor: string }>`
color: ${(props) => props.$color};
background-color: ${(props) => props.$bgColor};
`;
export default ({ rank, className = '' }) => {
const { t } = nx.useIntl();
const { icon, color, bgColor } = RANK_LIST[rank - 1];
return (
<Container
$color={color}
$bgColor={bgColor}
className={cx(className, 'fcc rounded-[1rem] px-2.5 f-3 fw-5 lh-5.5 x-1')}>
<img src={icon} width={16} alt="consultant rank" />
{t(`pages.main.consultant.rank.${rank - 1}`)}
</Container>
);
};
另一个 withConfig
const Container = styled.div.withConfig({
shouldForwardProp: (prop) => !['color', 'bgColor'].includes(prop),
})<{ color: string; bgColor: string }>`
color: ${(props) => props.color};
background-color: ${(props) => props.bgColor};
`;
常用的 color 方法
- 记得配置成App内全局
rgba/lighten/darken
npm i @jswork/color-rgba
npm i @jswork/color-lighten
npm i @jswork/color-darken
export const LoginFooter = styled.footer`
font-size: 14px;
color: ${rgba('#fff', 0.8)};
position: absolute;
bottom: 24px;
width: 100%;
text-align: center;
`;
each 等循环
import styled from 'styled-components';
export const STATUS_COLORS = [
{ label: 'Relative', status: 'relative', color: ['#03DCA4', '#D6D6D6'] },
{ label: 'Neutral', status: 'neutral', color: ['#F9F9F9', '#D6D6D6'] },
{ label: 'Positive', status: 'positive', color: ['#FF8886', '#D6D6D6'] },
{ label: 'Important', status: 'important', color: ['#FFCE00', '#FFFFFF'] },
{ label: 'Domain', status: 'domain', color: ['#1890FF3D', '#1890FF3D'] },
];
const Container = styled.div`
${STATUS_COLORS.map(
(item) =>
`&[data-status='${item.status}'] { > i { background: ${item.color[0]}; border-color: ${item.color[1]}; }`
)}
`;
export default (props) => {
return <Container>Legend</Container>;
};
默认属性
const StyledContainer = styled.section.attrs((props) => ({
width: props.width || "100%",
hasPadding: props.hasPadding || false,
}))`
--container-padding: 20px;
width: ${(props) => props.width}; // Falls back to 100%
padding: ${(props) =>
(props.hasPadding && "var(--container-padding)") || "none"};
`;
实现extend(其实是换个写法)
// 原来的
const StyledContainer = styled.section`
max-width: 1024px;
padding: 0 20px;
margin: 0 auto;
`;
const StyledSmallContainer = styled.section`
max-width: 1024px;
padding: 0 10px;
margin: 0 auto;
`;
const StyledContainer = styled.section`
max-width: 1024px;
padding: 0 20px;
margin: 0 auto;
`;
// Inherit StyledContainer in StyledSmallConatiner
const StyledSmallContainer = styled(StyledContainer)`
padding: 0 10px;
`;
全局 Style
- 使用
createGlobalStyle
- 看这个组件:
GlobalStyle
import React from 'react';
import { createGlobalStyle } from 'styled-components';
import Router from '@/views/Router';
import AppProvider from '@/providers';
const GlobalStyle = createGlobalStyle`
#app {
width: 100%;
height: 100%;
}
`;
function App() {
return (
<React.StrictMode>
<AppProvider>
<Router />
</AppProvider>
<GlobalStyle />
</React.StrictMode>
);
}
export default App;
调试
让 styled-component 定义的组件,在开发的时候,有名称出现。
- https://github.com/styled-components/babel-plugin-styled-components
- https://styled-components.com/docs/tooling#babel-plugin
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import svgr from 'vite-plugin-svgr';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react({
babel: {
plugins: [
[
'babel-plugin-styled-components',
{
displayName: true,
fileName: false,
},
],
],
},
}),
svgr(),
],
resolve: {
alias: {
'@': '/src',
},
},
});