主题定制方案
组件开发规范和主题定制方案是前端工程化中不可或缺的部分,良好的规范能提升代码可维护性,而灵活的定制方案则能适应多样化需求。下面从组件设计原则、代码规范、主题架构等方面展开具体说明。
组件设计原则
组件开发需遵循原子化设计理念,将UI拆分为可复用的最小单元。典型划分方式包括:
- 基础组件:按钮、输入框等基础交互元素
- 复合组件:由基础组件组合而成的功能块(如表单)
- 业务组件:包含特定业务逻辑的定制组件
// 基础按钮组件示例
const Button = ({
type = 'primary',
size = 'medium',
children,
onClick
}) => {
const classNames = `btn btn-${type} btn-${size}`;
return (
<button className={classNames} onClick={onClick}>
{children}
</button>
);
};
代码规范标准
文件结构
推荐按功能组织文件结构:
components/
├── Button/
│ ├── index.tsx
│ ├── style.module.scss
│ └── test.tsx
└── Form/
├── Input.tsx
└── Select.tsx
命名约定
- 组件采用PascalCase命名(如
DatePicker
) - 样式类名使用BEM规范(如
btn__icon--disabled
) - 事件处理函数以
handle
前缀开头(如handleClick
)
Props设计
遵循单向数据流原则,props应具备:
- 明确的类型定义
- 合理的默认值
- 完备的TS类型声明
interface ModalProps {
visible: boolean;
title?: string;
width?: number;
onClose: () => void;
children: React.ReactNode;
}
主题定制方案
CSS变量体系
建立全局主题变量体系实现动态换肤:
:root {
--color-primary: #1890ff;
--color-success: #52c41a;
--font-size-base: 14px;
--spacing-unit: 8px;
}
.dark-theme {
--color-primary: #177ddc;
--color-text: rgba(255,255,255,0.85);
}
主题配置文件
采用JSON结构管理主题变量:
{
"light": {
"palette": {
"primary": "#1890ff",
"text": "rgba(0,0,0,0.85)"
}
},
"dark": {
"palette": {
"primary": "#177ddc",
"text": "rgba(255,255,255,0.85)"
}
}
}
运行时主题切换
通过Context实现动态主题:
const ThemeContext = createContext();
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
<div className={`theme-${theme}`}>
{children}
</div>
</ThemeContext.Provider>
);
};
样式处理方案
CSS-in-JS方案
使用styled-components实现样式封装:
const StyledButton = styled.button`
padding: ${props => props.size === 'large' ? '12px 24px' : '8px 16px'};
background: ${props => props.theme.primary};
border-radius: ${props => props.theme.borderRadius};
`;
Sass预处理
利用Sass特性增强样式可维护性:
// _variables.scss
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px
);
// mixins.scss
@mixin respond-to($breakpoint) {
@media (min-width: map-get($breakpoints, $breakpoint)) {
@content;
}
}
组件文档规范
Storybook集成
通过Storybook展示组件用例:
// Button.stories.js
export default {
title: 'Components/Button',
component: Button
};
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
type: 'primary',
children: 'Primary Button'
};
Props表格生成
使用react-docgen自动生成文档:
/**
* 通用按钮组件
* @param {string} type - 按钮类型 (primary|dashed|link)
* @param {function} onClick - 点击事件处理器
*/
function Button({ type, onClick }) {
// ...
}
版本兼容策略
语义化版本控制
遵循SemVer规范进行版本管理:
- MAJOR:破坏性变更
- MINOR:向后兼容的功能新增
- PATCH:问题修复
废弃策略
采用渐进式废弃方案:
- 先标记
@deprecated
- 保留至少一个主版本周期
- 提供迁移指南
/**
* @deprecated since v2.0, use <NewComponent /> instead
*/
class OldComponent extends React.Component {
// ...
}
性能优化要点
组件懒加载
使用React.lazy实现按需加载:
const LazyComponent = React.lazy(() => import('./HeavyComponent'));
function Wrapper() {
return (
<Suspense fallback={<Spinner />}>
<LazyComponent />
</Suspense>
);
}
样式作用域
通过CSS Modules避免样式污染:
import styles from './Button.module.css';
function Button() {
return <button className={styles.root}>Submit</button>;
}
测试验证体系
单元测试示例
使用Jest+Testing Library:
test('Button click triggers callback', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick} />);
fireEvent.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalled();
});
视觉回归测试
通过Storybook Chromatic捕获UI变更:
# 执行视觉测试
npx chromatic --project-token=<your_token>
多端适配方案
响应式设计
使用Hook处理响应式布局:
function useBreakpoint() {
const [breakpoint, setBreakpoint] = useState('');
useEffect(() => {
const checkSize = () => {
const width = window.innerWidth;
if (width < 768) setBreakpoint('mobile');
else if (width < 1024) setBreakpoint('tablet');
else setBreakpoint('desktop');
};
window.addEventListener('resize', checkSize);
return () => window.removeEventListener('resize', checkSize);
}, []);
return breakpoint;
}
移动端适配
通过viewport单位实现弹性布局:
.container {
padding: calc(1vw + 8px);
font-size: clamp(14px, 2vw, 16px);
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn