ホームページ >ウェブフロントエンド >jsチュートリアル >フロントエンド プロジェクトのコンポーネント フォルダーを整理する
フォルダー構造フロントエンド プロジェクトのコンポーネントは重要です。プロジェクトの開発と維持が容易になるからです。特に大規模なコンポーネントや複雑なコンポーネントを扱う場合、フォルダーを整理するとコードが整理され、見つけやすく、理解しやすくなります。
フォルダー構造は次のとおりです。さまざまな形式のコンポーネントを使用して開発されたプロジェクトで一般的に使用されますNext.js および TypeScript:
1.アトミック デザイン は、コンポーネントをその複雑さと機能に応じて分割する設計概念です。原子、分子、生物、テンプレート、ページの 5 つのレベルに分かれています。
src/ └── components/ ├── atoms/ # Small, reusable elements (e.g., buttons, inputs) │ ├── Button.tsx │ ├── Input.tsx │ ├── Icon.tsx │ └── ... # Additional atoms │ ├── molecules/ # Combinations of atoms (e.g., form groups) │ ├── FormInput.tsx │ ├── NavLink.tsx │ └── ... # Additional molecules │ ├── organisms/ # Complex UI components (e.g., headers, cards) │ ├── Header.tsx │ ├── Card.tsx │ ├── Footer.tsx │ └── ... # Additional organisms │ ├── templates/ # Page templates (layouts with placeholders) │ ├── MainLayout.tsx │ ├── DashboardLayout.tsx │ └── ... # Additional templates │ └── pages/ # Page-specific components (used directly in pages) ├── HomePage.tsx ├── AboutPage.tsx └── ... # Additional page components例:
import React from 'react'; interface ButtonProps { label: string; onClick: () => void; type?: 'button' | 'submit' | 'reset'; disabled?: boolean; } const Button: React.FC<ButtonProps> = ({ label, onClick, type = 'button', disabled = false }) => ( <button type={type} onClick={onClick} disabled={disabled} className="btn"> {label} </button> ); export default Button;分子: FormInput.tsx
import React from 'react'; import Input from '../atoms/Input'; import Label from '../atoms/Label'; interface FormInputProps { label: string; value: string; onChange: (value: string) => void; } const FormInput: React.FC<FormInputProps> = ({ label, value, onChange }) => ( <div className="form-input"> <Label text={label} /> <Input value={value} onChange={onChange} /> </div> ); export default FormInput;生物: Header.tsx
import React from 'react'; import NavLink from '../molecules/NavLink'; import Logo from '../atoms/Logo'; const Header: React.FC = () => ( <header className="header"> <Logo /> <nav> <NavLink href="/" label="Home" /> <NavLink href="/about" label="About" /> <NavLink href="/contact" label="Contact" /> </nav> </header> ); export default Header;2.
src/ └── components/ ├── authentication/ # Components related to authentication │ ├── Login.tsx │ ├── Signup.tsx │ └── PasswordReset.tsx │ ├── dashboard/ # Components specific to the dashboard │ ├── DashboardHeader.tsx │ ├── DashboardSidebar.tsx │ └── StatsCard.tsx │ ├── userProfile/ # Components for user profile │ ├── ProfileHeader.tsx │ ├── EditProfileForm.tsx │ └── Avatar.tsx │ ├── shared/ # Shared or common components across features │ ├── Button.tsx │ ├── Modal.tsx │ └── ... # Additional shared components │ └── layout/ # Layout components ├── Header.tsx ├── Footer.tsx └── Sidebar.tsx例:
import React, { useState } from 'react'; import Button from '../shared/Button'; import FormInput from '../shared/FormInput'; const Login: React.FC = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleLogin = () => { // Logic for login }; return ( <div className="login"> <h2>Login</h2> <FormInput label="Email" value={email} onChange={setEmail} /> <FormInput label="Password" value={password} onChange={setPassword} /> <Button label="Login" onClick={handleLogin} /> </div> ); }; export default Login;ダッシュボード: StatsCard.tsx
import React from 'react'; interface StatsCardProps { title: string; value: number; icon: React.ReactNode; } const StatsCard: React.FC<StatsCardProps> = ({ title, value, icon }) => ( <div className="stats-card"> <div className="stats-card-icon">{icon}</div> <div className="stats-card-info"> <h3>{title}</h3> <p>{value}</p> </div> </div> ); export default StatsCard;3.
src/ └── components/ ├── domain/ │ ├── product/ # Components related to product domain │ │ ├── ProductCard.tsx │ │ ├── ProductList.tsx │ │ └── ProductDetail.tsx │ │ │ ├── cart/ # Components for cart domain │ │ ├── CartItem.tsx │ │ ├── CartSummary.tsx │ │ └── CartIcon.tsx │ │ │ ├── user/ # Components for user domain │ │ ├── UserAvatar.tsx │ │ ├── UserProfile.tsx │ │ └── UserSettings.tsx │ │ │ └── ... # Additional domain-specific components │ ├── ui/ # UI elements (atoms, molecules, etc.) │ ├── atoms/ │ ├── molecules/ │ └── organisms/ │ └── layout/ # Layout components ├── Header.tsx ├── Footer.tsx └── Sidebar.tsx例:
import React from 'react'; interface ProductCardProps { name: string; price: number; imageUrl: string; onAddToCart: () => void; } const ProductCard: React.FC<ProductCardProps> = ({ name, price, imageUrl, onAddToCart }) => ( <div className="product-card"> <img src={imageUrl} alt={name} className="product-card-image" /> <div className="product-card-info"> <h3>{name}</h3> <p>${price.toFixed(2)}</p> <button onClick={onAddToCart}>Add to Cart</button> </div> </div> ); export default ProductCard;カート: Cartsummary.tsx
import React from 'react'; interface CartSummaryProps { totalItems: number; totalPrice: number; } const CartSummary: React.FC<CartSummary Props> = ({ totalItems, totalPrice }) => ( <div className="cart-summary"> <h3>Cart Summary</h3> <p>Total Items: {totalItems}</p> <p>Total Price: ${totalPrice.toFixed(2)}</p> <button>Checkout</button> </div> ); export default CartSummary;4.
Storybook を使用した コンポーネント駆動開発 (CDD)。これにより、メイン アプリケーションとは別の形式でコンポーネントを開発およびテストできます
src/ └── components/ ├── Button/ │ ├── Button.tsx # Component implementation │ ├── Button.stories.tsx # Storybook stories │ ├── Button.test.tsx # Unit tests │ └── Button.module.css # Component-specific styles │ ├── Input/ │ ├── Input.tsx │ ├── Input.stories.tsx │ ├── Input.test.tsx │ └── Input.module.css │ ├── Modal/ │ ├── Modal.tsx │ ├── Modal.stories.tsx │ ├── Modal.test.tsx │ └── Modal.module.css │ └── ... # Additional component folders例:
import React from 'react'; import styles from './Button.module.css'; interface ButtonProps { label: string; onClick: () => void; variant?: 'primary' | 'secondary'; } const Button: React.FC<ButtonProps> = ({ label, onClick, variant = 'primary' }) => ( <button className={`${styles.btn} ${styles[variant]}`} onClick={onClick}> {label} </button> ); export default Button;ボタン: Button.stories.tsx (ストーリーブック)
import React from 'react'; import { Meta, Story } from '@storybook/react'; import Button, { ButtonProps } from './Button'; export default { title: 'Components/Button', component: Button, } as Meta; const Template: Story<ButtonProps> = (args) => <Button {...args} />; export const Primary = Template.bind({}); Primary.args = { label: 'Primary Button', onClick: () => console.log('Primary Button Clicked'), variant: 'primary', }; export const Secondary = Template.bind({}); Secondary.args = { label: 'Secondary Button', onClick: () => console.log('Secondary Button Clicked'), variant: 'secondary', };5.
src/ └── components/ ├── shared/ # Shared components across the application │ ├── Button/ │ │ ├── Button.tsx │ │ └── Button.module.css │ │ │ ├── Modal/ │ │ ├── Modal.tsx │ │ └── Modal.module.css │ │ │ └── ... # Additional shared components │ ├── featureSpecific/ # Feature-specific components │ ├── UserProfile/ │ │ ├── ProfileHeader.tsx │ │ ├── ProfileDetails.tsx │ │ └── Avatar.tsx │ │ │ ├── ProductList/ │ │ ├── ProductCard.tsx │ │ └── ProductFilter.tsx │ │ │ └── ... # Additional feature-specific components │ └── layout/ # Layout components ├── Header.tsx ├── Footer.tsx └── Sidebar.tsx
import React from 'react'; import styles from './Modal.module.css'; interface ModalProps { title: string; isOpen: boolean; onClose: () => void; } const Modal: React.FC<ModalProps> = ({ title, isOpen, onClose, children }) => { if (!isOpen) return null; return ( <div className={styles.modalOverlay}> <div className={styles.modal}> <h2>{title}</h2> <button className={styles.closeButton} onClick={onClose}> × </button> <div className={styles.modalContent}>{children}</div> </div> </div> ); }; export default Modal;
import React from 'react'; interface ProfileHeaderProps { name: string; bio: string; avatarUrl: string; } const ProfileHeader: React.FC<ProfileHeaderProps> = ({ name, bio, avatarUrl }) => ( <div className="profile-header"> <img src={avatarUrl} alt={name} className="profile-avatar" /> <h1>{name}</h1> <p>{bio}</p> </div> ); export default ProfileHeader;
ด้วยข้อมูลและแนวทางเหล่านี้ หวังว่าคุณจะสามารถจัดโครงสร้างในโฟลเดอร์ components ของโปรเจคได้อย่างมีประสิทธิภาพและเหมาะสมกับความต้องการของโปรเจคของคุณ!
以上がフロントエンド プロジェクトのコンポーネント フォルダーを整理するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。