发布于 2026-01-06 4 阅读
0

使用 Styled Components 进行主题化

使用 Styled Components 进行主题化

使用 Styled Components 为 Web 应用程序创建主题的指南。

为什么要设定主题?

  • 主题有助于为您的应用程序创建独特的标识。主题可以将特定颜色、长度或阴影的所有用法抽象到一个统一的地方,以便所有用例都能遵循该主题。
  • 修改起来更容易。无论你当前的应用程序多么稳定,设计师总会遇到需要调换两种颜色的棘手情况。如果你的应用程序里到处都使用了颜色,那将会非常麻烦。如果你认为可以通过查找和替换来解决,请务必考虑CSS 中所有表示颜色的方法。

如何设置主题?

Styled Components 内置了一个主题提供程序ThemeProvider来帮助你完成这项工作。主题提供程序类似于React 上下文提供程序(本质上就是一个上下文提供程序)。你需要将内容包裹在主题提供程序中ThemeProvider,然后就可以开始了:

import { ThemeProvider } from 'styled-components';

function App() {
  return (
    <ThemeProvider theme={{}}>
      <p>All the other stuff goes here...</p>
    </ThemeProvider>
  );
}

主题可以是任何简单的 POJO。例如:

const theme = {
  colors: {
    primary: `yellow`,
    secondary: `red`,
  }
}
return (
  <ThemeProvider theme={theme}>
  </ThemeProvider>
);

如何获取主题?

可以通过使用样式组件来访问主题props.theme。唯一需要注意的是,Button渲染此组件的位置应该被包裹在其父组件的某个位置,该父组件ThemeProvider提供了主题属性theme

const Button = styled(Button)`
  background-color: ${props => props.theme.primary};
`;

但是如果它没有被包裹在 `<div>` 标签中呢ThemeProvider?如果您相信创建的组件即使没有上下文父组件也能正常工作,那么您应该给它赋予一些主题defaultProps

const Button = styled(Button)`
  background-color: ${props => props.theme.colors.primary};
`;

Button.defaultProps = {
  theme: {
    colors: {
      primary: 'transparent',
    },
  },
};

嵌套主题

多个主题提供程序可以相互嵌套。组件会从与其嵌套位置最近的主题提供程序中获取主题。

const Button = styled.button`
  background-color: ${props => props.theme.colors.primary};
`;
const theme = {
  colors: {
    primary: `yellow`,
  }
}
return (
  <ThemeProvider theme={theme}>
    <Button>Primary Button</Button>
    <ThemeProvider theme={specialTheme}>
      <Button>Special Button</Button>
    </ThemeProvider>
  </ThemeProvider>
);

Styled Components 的另一项强大功能是嵌套主题提供程序。Styled Components 会将从父组件接收到的当前主题作为参数传递给该组件,您可以使用该参数来操作主题或为其添加值。

import Navbar from "./Navbar";

const theme = (currentTheme) => ({
  ...currentTheme,
  navbar: {
    height: "6rem",
  },
});

return (
  <ThemeProvider theme={theme}>
    <ThemeProvider theme={specialTheme}>
      <Navbar />
    </ThemeProvider>
  </ThemeProvider>
);

变体

变体(Various)是我们创建能够根据属性(props)进行调整的组件的一种方式。您可能在一些 UI 库中见过它们:

<Button primary>Primary Button</Button>
<Button secondary>Secondary Button</Button>

传统方式

使用 styled-components,您可以根据 props 进行调整。

const Button = styled.button`
  ${props => props.primary && `
    background-color: ${props.theme.colors.primary};
  `}
  ${props => props.secondary && `
    background-color: ${props.theme.colors.secondary};
  `}
`;

风格化主题

您可以想象,传统的构建变体的方法在大规模应用时会非常麻烦,尤其是在构建设计系统时。

Styled Components 系列有一个名为styled theming 的库。它提供了一个更易于使用的 API,用于创建和维护基于变体的样式。例如,要创建一个在浅色和深色模式下显示不同的按钮:

import styled, {ThemeProvider} from 'styled-components';
import theme from 'styled-theming';

const backgroundColor = theme('mode', {
  light: '#f1c40f',
  dark: '#f39c12',
});

const Button = styled.div`
  background-color: ${backgroundColor};
`;

export default function App() {
  return (
    <ThemeProvider theme={{ mode: 'light' }}>
      <Button>
        Primary Button
      </Button>
    </ThemeProvider>
  );
}

好的,但如果我们需要创建这个的第二个变体呢?这就需要variants用到函数了。

import styled, {ThemeProvider} from 'styled-components';
import theme from 'styled-theming';

const backgroundColor = theme('mode', 'variant', {
  primary: {
    light: '#f1c40f',
    dark: '#f39c12',
  },
  secondary: {
    light: '#2ecc71',
    dark: '#27ae60',
  },
});

const Button = styled.div`
  background-color: ${backgroundColor};
`;

export default function App() {
  return (
    <ThemeProvider theme={{ mode: 'light' }}>
      <Button variant="primary">
        Primary Button
      </Button>
      <Button variant="secondary">
        Secondary Button
      </Button>
    </ThemeProvider>
  );
}

你还用过哪些 styled-components 的神奇技巧✨?关于如何在 TypeScript 中使用 styled-components,请参阅我的相关文章

我每月都会发布一份简报,详细介绍当月网站平台的所有动态。您可以在 Buttondown 上阅读往期内容并订阅。

文章来源:https://dev.to/boywithsilverwings/theming-with-styled-components-3ig2