React学习: styled-components

常用用法,记录
更新于: 2024-11-19 13:07:15

$ 开头的变量

如果不用这个,就会出现 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 定义的组件,在开发的时候,有名称出现。

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',
    },
  },
});