【配置化 CRUD 01】搜索重置组件:封装与复用
一:前言
在后台管理系统的配置化 CRUD 开发中,搜索+重置是高频组合场景,几乎所有列表页都需要通过搜索筛选数据、通过重置恢复初始查询状态等等...。基于此,本文将详细讲解「搜索重置组件」的封装思路及使用方法,该组件基于Vue3 + Element Plus 开发,支持配置化扩展、响应式联动,可直接集成到配置化 CRUD 体系中,提升开发效率与代码一致性。
二:解决问题
封装搜索重置组件主要为了解决以下几个问题:
1.代码冗余 : 每个列表页都要重复编写表单结构、搜索按钮、重置按钮,以及对应的点击事件、数据校验逻辑;
2.风格不统一:不同开发人员编写的搜索表单,在布局、按钮尺寸、标签宽度、间距等细节上可能存在差异;
3.维护成本高:当需要修改搜索表单的布局、按钮样式,需要逐个页面排查修改;
...
三:具体实现
在开始之前,请先阅读一下本专栏的第一篇文章,动态表单的实现是搜索重置组件的基础:
![]()
接下来我们可以思考一下一个通用的搜索重置组件具备的基本功能:
1.搜索项的展示
2.搜索项默认展示搜索初始值
3.搜素与重置按钮功能
...
扩展功能:
1.搜索表单项的联动
2.搜索表单项的校验
...
接下来我们一步一步来实现:
3.1 基础功能实现
先完成最简单的部分 : 展示搜索项和搜索重置按钮、以及基本样式统一处理
组件基础实现:
type SearchPrams = {
schema?: FormOptions[] // 配置表
search?: () => void // 搜索回调
reset?: () => void // 重置回调
labelWidth?: string,
flex?: number
}
const props = withDefaults(defineProps<SearchPrams>(), {
schema: {},
labelWidth:'140px',
flex:5
})
const codeFormRef = ref(null)
//搜索
const search = async () => {
const data = await codeFormRef?.value?.getData()
emits('search', data)
}
//重置
const reset = () => {
codeFormRef?.value?.resetFields('')
emits('reset', {})
}
<div class="sea-box">
<CodeForm
class="form-box"
:style="{ flex: props?.flex || 5 }"
layoutType="cell"
ref="codeFormRef"
:schema="schema"
:labelWidth="props.labelWidth"
>
</CodeForm>
<div class="sea-btn-box">
<div>
<ElButton
type="primary"
:style="{ width: '80px' }"
@click="search"
>{{ $t('Search') }}</ElButton
>
<ElButton
:style="{ width: '80px', marginLeft: '15px' }"
@click="reset"
>{{ $t('Reset') }}</ElButton
>
</div>
</div>
</div>
<style scoped>
.sea-btn-box {
flex: 1;
display: flex;
justify-content: flex-end;
}
.form-box {
flex: 5;
}
.sea-box {
display: flex;
padding: 20px;
padding-bottom: 0;
padding-top: 0;
}
</style>
外部定义配置表:
const searchColumn = [
{
label: '姓名',
prop: 'name',
component: 'Input',
},
{
label: '年龄',
prop: 'age',
component: 'Input',
},
{
label: '上学阶段',
prop: 'jieduan',
component: 'Select',
componentProps: {
options: [
{
label: '幼儿园',
value: 1
},
{
label: '其他阶段',
value: 2
}
]
}
},
]
引入组件使用:
<Search
:schema="allshema.searchcolumns"
@search="(params) => console.log('点击查询:',{params})"
@reset="() => setSearchParams({}, true, true)"
>
</Search>
运行截图:
![]()
到这一步我们就已经实现了基本功能:展示表单、统一风格、查询重置。
当然我们可能会想要某些表单项具有初始值,或者不展示重置按钮,只要组件内部稍加改造一下就行:
type SearchPrams = {
showSearch?: boolean // 展示搜索按钮
showReset?: boolean // 展示重置按钮
schema?: any // 配置表
search?: () => any
reset?: () => any
labelWidth?: string,
flex?: number
}
<div class="sea-btn-box">
<div>
<ElButton
v-if="showSearch"
type="primary"
:style="{ width: '80px' }"
@click="search"
>{{ $t('Search') }}</ElButton
>
<ElButton
v-if="showReset"
:style="{ width: '80px', marginLeft: '15px' }"
@click="reset"
>{{ $t('Reset') }}</ElButton
>
</div>
</div>
外部引入:
const searchColumn = [
{
label: '姓名',
prop: 'name',
initValue: '初始化名字',
component: 'Input',
},
...
]
<Search
:schema="searchColumn"
@search="(params) => console.log('点击查询:',{params})"
:showReset="false"
>
</Search>
运行截图:
![]()
这样就实现了按钮的展示与隐藏以及初始化默认值。
3.2 扩展功能实现
接下来我们继续实现一下扩展功能:
1.表单项的联动
利用动态表单组件内置的 setValues、setSchemas方法,
组件内部增加方法定义及暴露:
const setValues = (data: any) => {
codeFormRef?.value?.setValues(data)
}
const setSchemas = (data: any) => {
codeFormRef?.value?.setSchemas(data)
}
defineExpose({
getData,
setValues,
setSchemas
})
外部增加搜索组件的ref引用:
const searchRef: any = ref(null)
const searchColumn = [
{
label: '姓名',
prop: 'name',
initValue: '初始化名字',
component: 'Input',
componentProps: {
onInput: (e: any) => {
console.log('姓名输入框输入事件', e)
searchRef.value?.setSchemas([
{
prop: 'age',
path: 'componentProps.placeholder',
value: `请输入${e}的年龄`
}
])
}
}
},
{
label: '年龄',
prop: 'age',
component: 'Input',
},
...
]
<Search
ref="searchRef"
:schema="allshema.searchcolumns"
@search="setSearchParams"
@reset="() => setSearchParams({}, true, true)"
>
</Search>
运行截图:
![]()
这样就实现了搜索表单项之间的联动。
2.表单项的校验
组件内部改动:
type SearchPrams = {
showSearch?: boolean // 展示搜索
showReset?: boolean // 展示重置按钮
isVaildSearch?: boolean // 是否校验搜索
schema?: any // 配置表
search?: () => any
reset?: () => any
labelWidth?: string,
flex?: number
}
const props = withDefaults(defineProps<SearchPrams>(), {
showSearch: true,
showReset: true,
isVaildSearch: false,
schema: {}, // 表单配置
labelWidth:'140px',
flex:5
})
const search = async () => {
if(props.isVaildSearch) {
const valid = await codeFormRef?.value?.validate();
if(!valid) return;
}
const data = await codeFormRef?.value?.getData()
emits('search', data)
}
外部引入使用:
const searchColumn = [
...,
{
label: '年龄',
prop: 'age',
component: 'Input',
formItemProps: {
rules:[
{
required: true,
message: '请输入年龄',
trigger: 'blur'
}
]
}
},
...
]
<Search
ref="searchRef"
:schema="searchColumn"
@search="(params) => console.log('点击查询:',{params})"
:showReset="false"
:isVaildSearch="true"
>
</Search>
运行截图:
![]()
这样就实现了搜索表单项的表单校验。
以上就是搜索重置组件的核心实现步骤~