Vue3 + Element Plus 实战:通用搜索组件CustomSearch封装与应用
在中后台管理系统开发中,搜索功能是高频场景,不同页面的搜索条件往往重复且逻辑相似。基于Vue3 + Element Plus封装通用搜索组件CustomSearch,能大幅提升开发效率、降低代码冗余。本文结合实际项目代码,从组件封装思路、配置设计、页面集成全流程,详解CustomSearch的实现与落地。
一、核心思路:配置化驱动组件
CustomSearch的核心设计理念是配置化:通过一份JSON配置文件定义搜索项(输入框、下拉框、时间选择器等),组件根据配置自动渲染UI,并统一处理搜索逻辑。结合项目中MyInput、MySelect、MyDateTimePicker等基础组件(本文默认这些是基于Element Plus基础组件的二次封装,核心逻辑与原生一致),最终实现“一处配置,多处复用”。
技术栈基础
- 框架:Vue3(Setup语法糖)
- UI库:Element Plus
- 核心思想:Props透传 + 事件派发 + 配置化渲染
二、先看最终效果:Dashboard页面的使用
在src/views/Dashboard/index.vue中,CustomSearch的使用非常简洁:
新增
仅需传入searchConfig配置、监听updateQueryData事件,就能实现完整的搜索功能,这就是配置化的优势。
三、核心文件拆解
1. 配置文件:tableConfig.js(Dashboard目录下)
首先定义搜索配置searchConfig,这是组件渲染的“数据源”,每一项对应一个搜索控件:
// src/views/Dashboard/tableConfig.js
export const searchConfig = [
// 搜索项1:项目名称(输入框)
{
label: "项目名称",
prop: "projectName", // 绑定的查询参数key
type: "input", // 控件类型:输入框
placeholder: "请输入项目名称",
clearable: true // 是否显示清空按钮
},
// 搜索项2:所属二级菜单(下拉框)
{
label: "所属二级菜单",
prop: "menuId",
type: "select", // 控件类型:下拉框
placeholder: "请选择二级菜单",
clearable: true,
options: [] // 下拉选项(页面加载时动态赋值)
},
// 搜索项3:项目状态(下拉框)
{
label: "项目状态",
prop: "projectStatus",
type: "select",
placeholder: "请选择项目状态",
clearable: true,
options: [
{ label: "上架", value: 1 },
{ label: "下架", value: 2 },
{ label: "删除", value: 0 }
]
},
// 搜索项4:更新人(输入框)
{
label: "更新人",
prop: "updater",
type: "input",
placeholder: "请输入更新人",
clearable: true
},
// 搜索项5:时间范围(时间选择器)
{
label: "创建时间",
prop: "createTime",
type: "datetime", // 控件类型:时间选择器
range: true, // 范围选择
format: "YYYY-MM-DD HH:mm:ss"
}
];
配置项设计原则:
prop:与queryParams的key一一对应,保证参数绑定一致性;type:指定控件类型(input/select/datetime),对应MyInput/MySelect/MyDateTimePicker;- 其他属性:透传给底层组件(如
clearable、placeholder、options等)。
2. 通用搜索组件:CustomSearch/index.vue
组件核心逻辑:遍历searchConfig,根据type渲染对应控件,统一处理“搜索/重置/分页”逻辑。
模板部分(template)
搜索
重置
脚本部分(script setup)
3. Dashboard页面集成逻辑(index.vue)
步骤1:引入组件与配置
import CustomSearch from "@/components/CustomSearch/index.vue";
import { searchConfig } from "./tableConfig.js";
步骤2:定义查询参数
const queryParams = ref({
page:1,
limit:10,
projectName:'',
projectStatus:'',
updater:'',
menuId:''
});
步骤3:初始化动态配置(如下拉框选项)
// 获取二级菜单列表,赋值给searchConfig的options
const getSecondMenuFun = ()=>{
getSecondMenu().then(rs=>{
// 找到searchConfig中type为select、prop为menuId的项
const menuItem = searchConfig.find(item => item.prop === "menuId");
if (menuItem) {
menuItem.options = rs.list; // 动态赋值下拉选项
}
});
};
// 页面挂载时执行
onMounted(()=>{
getSecondMenuFun();
updateQueryData(); // 初始加载数据
});
步骤4:监听搜索组件的参数更新
const updateQueryData = (params, bool) => {
// 合并参数(新参数覆盖旧参数)
queryParams.value = { ...queryParams.value, ...params };
// 调用接口刷新表格数据
getProjectListFun(queryParams.value);
};
// 接口请求函数
const getProjectListFun = (params)=>{
getProjectList(params).then(rs=>{
tableData.value = rs.page.list;
total.value = rs.page.totalCount;
});
};
步骤5:自定义插槽(新增按钮)
新增
插槽的作用是保留组件扩展性:不同页面的搜索区可能需要“新增”“导出”等自定义按钮,通过插槽无需修改CustomSearch源码。
步骤6:基础组件拆解
核心逻辑:
- 对el-input做极简封装,透传style、placeholder等属性;
- 用localValue接收value props,实现值绑定;
- 保留clearable(清空按钮),适配中后台搜索场景。
核心优化:
- `支持labelKey/valueKey自定义,适配不同接口返回的字段名(如有的接口返回name/id,有的返回label/value)
- 透传clearable,支持清空选中值。
核心优化:
- 支持datetimerange(时间范围)类型,适配搜索场景的时间区间筛选;
- 通过automaticQuery控制是否选择后立即触发查询;
- 用customId关联查询参数的 key,方便父组件识别参数归属。
四、关键设计细节解析
1. 配置化的优势
- 低耦合:搜索项的增减/修改仅需调整
tableConfig.js,无需改组件代码; - 高复用:
CustomSearch可直接复用到Message、User等其他页面,仅需替换searchConfig; - 易维护:统一的搜索逻辑(重置、参数派发)集中在组件内,避免重复写业务逻辑。
2. 与Element Plus的结合
MyInput/MySelect/MyDateTimePicker本质是对el-input/el-select/el-date-picker的二次封装,核心是透传props和事件;el-form的inline属性实现搜索项横向排列,符合中后台UI设计习惯;- 事件派发遵循Vue3的单向数据流:组件内部不直接请求接口,仅把参数传给父组件,由父组件处理业务逻辑(如调用
getProjectList)。
3. 分页参数的处理
搜索组件默认集成分页参数(page/limit),原因是搜索与分页通常联动:
- 重置搜索时,分页重置为第1页;
- 切换分页时,搜索条件保留,仅更新
page参数; - 父组件的
updateQueryData方法统一接收所有参数,无需单独处理分页。
五、扩展与优化
1. 支持更多控件类型
可在searchConfig中扩展type,如radio、checkbox,只需在CustomSearch中增加对应分支:
2. 实时搜索
默认是点击“搜索”按钮触发查询,若需实时搜索(如输入框输入时立即查询),可在handleInputChange中触发emit:
const handleInputChange = () => {
clearTimeout(timer);
// 防抖:避免频繁请求
timer = setTimeout(() => {
emit("updateQueryData", { ...searchForm.value }, true);
}, 500);
};
3. 参数校验
可在searchConfig中增加rules字段,实现搜索项的表单校验:
// tableConfig.js
{
label: "项目名称",
prop: "projectName",
type: "input",
rules: [{ required: true, message: "请输入项目名称" }]
}
// CustomSearch/index.vue
// 引入ElForm的校验方法
const ruleFormRef = ref(null);
const handleSearch = () => {
ruleFormRef.value.validate((valid) => {
if (valid) {
emit("updateQueryData", { ...searchForm.value }, true);
}
});
};
六、总结
CustomSearch组件的封装核心是配置化 + 通用逻辑抽离:
- 以
searchConfig为核心,通过不同type渲染对应控件,实现UI的动态生成; - 统一处理“参数绑定、搜索、重置”逻辑,降低页面层的代码冗余;
- 通过插槽和事件派发,保证组件的扩展性和单向数据流;
- 在Dashboard页面中,仅需引入配置、监听事件,即可快速集成搜索功能。
这种封装方式不仅适用于搜索组件,也可推广到表格(如项目中的CustomTable)、弹窗(CustomEditDialog)等通用组件,是中后台Vue3项目提升开发效率的核心思路。
前端实战:基于Element Plus的CustomTable表格组件封装与应用








