Gatsby + TypeScript + styled-components | 组件封装 | 动态传参

207 阅读3分钟

在gatsby项目里用ts写活组件,以下是button和img的组件eg。

Button组件eg

index.tsx

在这个文件中,我们创建一个 Button 组件,接受 props 来动态定义其样式:

// index.tsx
import React from 'react';
import { StyledButton } from './style';

// 定义 ButtonProps 接口
interface ButtonProps {
  borderRadius?: 'small' | 'medium' | 'large';
  backgroundColor?: 'primary' | 'secondary' | 'danger';
  height?: 'small' | 'medium' | 'large';
  width?: 'small' | 'medium' | 'large';
  onClick?: () => void;
  children: React.ReactNode;
}

// 定义预设值
const borderRadiusValues = {
  small: '4px',
  medium: '8px',
  large: '16px',
};

const backgroundColorValues = {
  primary: '#007bff',
  secondary: '#6c757d',
  danger: '#dc3545',
};

const sizeValues = {
  small: '32px',
  medium: '48px',
  large: '64px',
};

// Button 组件
const Button: React.FC<ButtonProps> = ({
  borderRadius = 'medium',
  backgroundColor = 'primary',
  height = 'medium',
  width = 'medium',
  onClick,
  children,
}) => {
  return (
    <StyledButton
      borderRadius={borderRadiusValues[borderRadius]}
      backgroundColor={backgroundColorValues[backgroundColor]}
      height={sizeValues[height]}
      width={sizeValues[width]}
      onClick={onClick}
    >
      {children}
    </StyledButton>
  );
};

export default Button;

style.ts

在这个文件中,我们使用 styled-components 来定义 StyledButton 的样式:

// style.ts
import styled from 'styled-components';

interface StyledButtonProps {
  borderRadius: string;
  backgroundColor: string;
  height: string;
  width: string;
}

export const StyledButton = styled.button<StyledButtonProps>`
  border-radius: ${(props) => props.borderRadius};
  background-color: ${(props) => props.backgroundColor};
  height: ${(props) => props.height};
  width: ${(props) => props.width};
  color: white;
  border: none;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.3s;

  &:hover {
    filter: brightness(90%);
  }
`;

调用组件:

<Button borderRadius="large" backgroundColor="danger" height="small" width="large">
  Click Me
</Button>

说明:

  1. Props 接口定义ButtonProps 接口定义了按钮的可选样式属性。默认值被设置为 'medium' 和 'primary' 等。
  2. 预设值: 使用了几个对象来定义预设值,这些值可以根据项目需求进行调整。
  3. 动态样式: 在 StyledButton 中,使用 props 动态设置 border-radiusbackground-colorheight 和 width
  4. 按钮行为: 在 StyledButton 中添加了简单的悬停效果。
  5. 使用: 在你的应用中使用这个 Button 组件时,可以传入不同的属性来改变它的样式

这样,你就拥有了一个灵活且易于配置的 Button 组件,可以根据需要调整其外观和行为。

Img组件eg

index.tsx

在这个文件中,我们创建一个 Img 组件,接受一个 prop 来动态定义其图片路径:

// index.tsx
import React from 'react';
import { StyledImg } from './style';

// 定义 ImgProps 接口
interface ImgProps {
  src: string;
  alt?: string;
  width?: string;
  height?: string;
}

// Img 组件
const Img: React.FC<ImgProps> = ({ src, alt = 'image', width = '100px', height = '100px' }) => {
  return <StyledImg src={src} alt={alt} width={width} height={height} />;
};

export default Img;

style.ts

在这个文件中,我们使用 styled-components 来定义 StyledImg 的样式:

// style.ts
import styled from 'styled-components';

interface StyledImgProps {
  width: string;
  height: string;
}

export const StyledImg = styled.img<StyledImgProps>`
  width: ${(props) => props.width};
  height: ${(props) => props.height};
  object-fit: cover; // 保持图片比例
`;

调用组件:

import React from 'react';
import Img from './Img'; // 假设组件文件名为 Img

const App: React.FC = () => {
  return (
    <div>
      <Img src="path/to/image1.jpg" alt="First Image" width="200px" height="200px" />
      <Img src="path/to/image2.jpg" alt="Second Image" width="150px" height="150px" />
    </div>
  );
};

export default App;

说明:

  1. 接口定义ImgProps 接口定义了组件的属性,包括 src(图片路径)、alt(替代文本)、width 和 height
  2. 默认值: 为 altwidth 和 height 提供了默认值,确保在未提供这些属性时组件仍能正常工作。
  3. 样式组件StyledImg 使用了 styled-components 来定义样式,允许在组件中使用宽度和高度。
  4. object-fit: 使用 object-fit: cover 来保持图片的比例,不会因为容器的大小而变形。
  5. 使用:在你需要的地方使用 Img 组件时,只需传入不同的 src 属性即可动态改变图片。
  6. 路径管理: 确保传递给 src 的路径是相对于项目构建后的 public 目录,这样在生产环境中路径能正确解析。
  7. 灵活性: 通过调整 width 和 height,你可以控制图片的显示尺寸,这对于响应式设计非常有用。

通过这种方式,你可以创建一个灵活而简单的 Img 组件,能够根据应用的需求动态加载不同的图片。