摘要
在前端开发中,组件化是提高代码复用性和开发效率的关键。我将分享在实际项目中封装和使用高复用组件的经验,尤其是围绕 高级筛选组件 的设计展开讨论,并探讨如何通过组件化思维提升团队整体开发效率。
# 为什么需要自定义业务组件库?
虽然市面上已有很多成熟的 UI 组件库(如 Element UI、Ant Design 等),但它们往往只提供基础的 UI 组件。在实际业务中,我们经常需要基于这些基础组件进行组合,形成更符合业务需求的复合组件。
✅ 自定义业务组件库的优势:
- 提高复用效率:减少相似功能的重复开发。
- 统一交互体验:保证 UI/UX 一致性,提高用户体验。
- 降低维护成本:集中管理核心组件,避免分散维护。
- 加速开发流程:新功能可以更快速地搭建,提高团队协作效率。
# 1. 高级筛选组件案例分析
# 1.1 需求背景
在项目中,几乎每个 列表页面 都需要 筛选功能,且筛选条件通常分为两类:
1️⃣ 常用筛选条件:默认显示,使用频率高。
2️⃣ 高级筛选条件:默认隐藏,通过 "高级筛选" 按钮展开,使用频率较低。
如果在每个页面都单独实现这些逻辑,会导致 大量重复代码,且 交互体验不一致,不利于维护。
# 1.2 组件设计思路
📌 核心设计要点:
- 使用具名插槽分离内容:
default-filters插槽:放置常用筛选条件。advanced-filters插槽:放置高级筛选条件(默认隐藏)。
- 封装交互逻辑:
- 统一 展开 / 收起 控制。
- 统一 重置 / 查询 事件处理。
- 响应式布局适配不同屏幕尺寸。
- 事件通知机制:
- 通过
emit向父组件通知查询或重置操作,提高组件的灵活性。
- 通过
# 1.3 组件实现代码解析
<template>
<div class="advanced-filter-container">
<!-- 默认展示的筛选条件 -->
<div class="default-filters">
<slot name="default-filters"></slot>
<!-- 展开/收起按钮 -->
<div class="toggle-btn" @click="toggleAdvanced">
<span>{{ isAdvanced ? '收起' : '高级筛选' }}</span>
<i :class="['toggle-icon', isAdvanced ? 'up' : 'down']"></i>
</div>
</div>
<!-- 高级筛选条件区域 -->
<div class="advanced-filters" v-show="isAdvanced">
<slot name="advanced-filters"></slot>
</div>
<!-- 操作按钮区域 -->
<div class="filter-actions">
<button class="reset-btn" @click="handleReset">重置</button>
<button class="search-btn" @click="handleSearch">查询</button>
</div>
</div>
</template>
<script setup>
import { ref, defineEmits } from "vue";
const isAdvanced = ref(false);
const emit = defineEmits(["reset", "search"]);
const toggleAdvanced = () => {
isAdvanced.value = !isAdvanced.value;
};
const handleReset = () => {
emit("reset");
};
const handleSearch = () => {
emit("search");
};
</script>
<style scoped>
.advanced-filter-container {
padding: 16px;
background: #fff;
border-radius: 6px;
}
.default-filters {
display: flex;
align-items: center;
justify-content: space-between;
}
.toggle-btn {
cursor: pointer;
color: #007aff;
}
.filter-actions {
margin-top: 10px;
display: flex;
gap: 10px;
}
</style>
# 1.4 组件使用示例
<template>
<AdvancedFilter @reset="resetFilters" @search="searchUsers">
<!-- 默认显示的筛选条件 -->
<template #default-filters>
<div class="filter-item">
<label>用户名:</label>
<el-input v-model="filters.username" placeholder="请输入用户名"></el-input>
</div>
<div class="filter-item">
<label>状态:</label>
<el-select v-model="filters.status" placeholder="请选择状态">
<el-option label="正常" value="active"></el-option>
<el-option label="禁用" value="disabled"></el-option>
</el-select>
</div>
</template>
<!-- 高级筛选条件 -->
<template #advanced-filters>
<div class="filter-item">
<label>注册时间:</label>
<el-date-picker v-model="filters.dateRange" type="daterange"></el-date-picker>
</div>
</template>
</AdvancedFilter>
</template>
<script setup>
import { ref } from "vue";
import AdvancedFilter from "@/components/AdvancedFilter.vue";
const filters = ref({
username: "",
status: "",
dateRange: []
});
const resetFilters = () => {
filters.value = { username: "", status: "", dateRange: [] };
};
const searchUsers = () => {
console.log("查询用户", filters.value);
};
</script>
# 2. 组件封装的最佳实践
📌 1. 组件职责单一化:
每个组件尽量只负责 一个核心功能,避免过度封装。
📌 2. 组件参数可配置:
提供 props 控制组件行为,避免硬编码。
📌 3. 适配不同场景:
考虑 响应式布局,确保组件在移动端和 PC 端都能良好适配。
📌 4. 组件间通信:
- 父子组件 之间使用
props和emit进行通信。 - 跨组件通信 可使用
Pinia或Vuex进行全局状态管理。
# 3. 总结
🚀 完整组件封装流程:
1️⃣ 分析需求,确定复用场景(如筛选逻辑的共性)。
2️⃣ 设计 API 和插槽结构,确保组件 高内聚、低耦合。
3️⃣ 封装交互逻辑,如 事件处理、状态管理、样式适配。
4️⃣ 优化组件易用性,提供清晰的 文档 & 示例,方便团队复用。
通过组件化开发,我们不仅能 提高代码复用率,还能 保持项目结构清晰、提升开发效率,让整个团队的协作更高效!✨