Badge Component Design
Overview
The Badge component is a core component in this library used for displaying badges or small red dots. It adheres to the library's consistent design philosophy of "Separation of Concerns" and "Logic Abstraction." Through core logic like useBadgeComputed, it provides a complete and user-friendly badge management solution.
The Badge component focuses on handling badge content display, position control, and style adjustments, offering users a powerful and flexible badge presentation tool that supports dynamic content binding, position adjustment, and color customization.
Design Philosophy
Layered Architecture
The Badge component is strictly designed with a three-layer architecture:
- Structure Layer (
badge.vue) - Responsible for the component's DOM structure and basic layout. - Logic Layer (
badgeComputed.ts) - Handles complex reactive computations and interaction logic. - Presentation Layer (
badge.scss) - Defines the component's visual presentation and style rules.
Logic Abstraction
The Badge component abstracts complex logic into core functions:
useBadgeComputed- Handles core badge logic.useStyleComputed- Handles dynamic style generation.
This design allows the component itself to simply declare the required logic, while the specific computations are handled by the logic functions.
Core Feature Design
Structured Props Design
The props design for the Badge component is clean and straightforward:
export const badgeProps = {
/** Badge content */
content: {
type: [String, Number] as PropType<string | number>,
default: ''
},
/** Whether to display as a small red dot */
dot: {
type: Boolean,
default: false
},
/** Badge background color */
color: {
type: String,
default: '#ff4d4f'
},
/** Badge position */
position: {
type: String as PropType<BadgeProps['position']>,
default: 'top-right',
validator: (value: string) => {
return ['top-right', 'top-left', 'bottom-right', 'bottom-left'].includes(value);
}
},
/** Maximum display value */
max: {
type: Number,
default: 99,
validator: (value: number) => {
return value >= 0;
}
}
};This design provides sufficient flexibility to support various usage scenarios.
Dependency Injection Mechanism
The Badge component implements parent-child communication via Vue's Composition API:
const props = defineProps(badgeProps);
const {
displayContent,
badgeStyle,
wrapperStyle
} = useBadgeComputed(props);This design enables seamless collaboration between the Badge component and its parent container.
Style System Design
CSS Variable Control
The Badge component achieves style control through CSS variables:
· --badge-color - Controls badge background color.
Layout System
The Badge component supports flexible layout control: · Default Layout - Default positioning at top-right. · Position Adjustment - Controls positioning at four corners via the position property.
State Styles
The Badge component provides corresponding styles for different states:
· Default State - Standard badge style. · Dot State - Pure dot display mode. · Max Value State - Displays "max+" format when exceeding the maximum value.
Component Structure Design
Overall Structure
The overall structure of the Badge component is as follows:
<div class="my-badge-wrapper" :style="wrapperStyle">
<slot />
<span v-if="(content !== null && content !== '') || dot" class="my-badge" :class="{ 'dot': dot }" :style="badgeStyle">
{{ displayContent }}
</span>
</div>Component Hierarchy
The Badge component consists of two main parts:
- Container - .my-badge-wrapper - Wraps the entire badge and its content.
- Badge - .my-badge - Displays the actual badge content.
- Dot - .my-badge.dot - Special styling for dot mode.
Interaction Design
Dynamic Content Display
The Badge component supports multiple content display modes:
const displayContent = computed(() => {
if (props.dot) return '';
if (typeof props.content === 'number' && props.content > props.max) {
return `${props.max}+`;
}
return props.content;
});Dynamic Style Adjustment
The Badge component supports dynamic style adjustment:
const badgeStyle = useStyleComputed(props, {
propToStyleMap: {
color: 'backgroundColor',
},
customStyleLogic: (props, style) => {
switch (props.position) {
case 'top-right':
Object.assign(style, { top: '-5px', right: '-5px' });
break;
case 'top-left':
Object.assign(style, { top: '-5px', left: '-5px' });
break;
case 'bottom-right':
Object.assign(style, { bottom: '-5px', right: '-5px' });
break;
case 'bottom-left':
Object.assign(style, { bottom: '-5px', left: '-5px' });
break;
}
},
});Extensibility Design
The Badge component offers excellent extensibility:
- Content Binding: Dynamic content binding via the content property.
- Position Control: Defines badge position via the position property.
- Color Customization: Controls badge background color via the color property.
- Maximum Value Limit: Controls the maximum display value via the max property.
- Dot Mode: Switches to dot mode via the dot property.
Style Details
The Badge component features the following style handling characteristics:
- Responsive Design: Supports flexible layout adaptation.
- Consistency: Maintains style consistency with other library components.
- Error Feedback: Clear visual feedback on validation failure.
- Accessibility Design: Supports keyboard navigation and screen readers.
Performance Optimization
Performance is optimized through:
- Caching computation results using computed properties.
- Moving complex logic into independent functions.
- Avoiding unnecessary re-renders.
- Leveraging Vue 3 Composition API for runtime efficiency.
- Properly adding and removing event listeners.
Design Value
The Badge component embodies the design philosophy of our component library:
- Separation of Concerns: Complete decoupling of structure, style, and logic.
- High Reusability: Abstracting common logic via functions.
- Ease of Maintenance: Clear code structure and naming conventions.
- Strong Extensibility: Support for rich customization options.
- Consistency: Maintains a consistent design language with other components like Button, Icon, and Avatar.