父组件
<template>
<div>
<SearchForm
:form-items="searchItems"
:initial-values="initialValues"
@search="handleSearch"
@reset="handleReset"
>
<!-- 自定义插槽内容 -->
<template #custom-slot="{ form }">
<el-input
v-model="form.customField"
placeholder="自定义字段"
></el-input>
</template>
<!-- 额外操作按钮 -->
<template #extra-actions>
<el-button type="warning" @click="handleExport">导出</el-button>
</template>
</SearchForm>
<!-- 其他页面内容 -->
</div>
</template>
<script>
import SearchForm from '@/views/largeScreen/productionBusiness/components/searchForm.vue'
export default {
name: 'WorkOrderDetailList',
components: { SearchForm },
data() {
return {
initialValues: {
name: '默认值',
status: '1'
},
searchItems: [
{
label: '姓名',
prop: 'name',
type: 'input',
placeholder: '请输入姓名'
},
{
label: '状态',
prop: 'status',
type: 'select',
options: [
{ label: '启用', value: '1' },
{ label: '禁用', value: '0' }
]
},
{
label: '创建日期',
prop: 'createTime',
type: 'date',
dateType: 'daterange',
valueFormat: 'yyyy-MM-dd'
},
{
label: '自定义字段',
prop: 'customField',
type: 'slot',
slotName: 'custom-slot'
}
]
}
},
methods: {
handleSearch(params) {
console.log('搜索参数:', params)
// 调用API获取数据
},
handleReset() {
console.log('表单已重置')
},
handleExport() {
console.log('导出操作')
}
}
}
</script>
子组件
<template>
<div>
<el-form
ref="searchFormRef"
:model="formModel"
:inline="true"
:label-width="labelWidth"
class="search-form"
@submit.prevent="handleSearch"
>
<!-- 动态渲染搜索表单项 -->
<template v-for="(item, index) in formItems">
<!-- 输入框 -->
<el-form-item
:key="index"
v-if="item.type === 'input' || !item.type"
:label="item.label"
:prop="item.prop"
>
<el-input
v-model="formModel[item.prop]"
:placeholder="item.placeholder || `请输入${item.label}`"
clearable
@keyup.enter="handleSearch"
/>
</el-form-item>
<!-- 选择器 -->
<el-form-item
v-else-if="item.type === 'select'"
:label="item.label"
:prop="item.prop"
>
<el-select
v-model="formModel[item.prop]"
:placeholder="item.placeholder || `请选择${item.label}`"
clearable
filterable
style="width: 100%"
>
<el-option
v-for="opt in item.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select>
</el-form-item>
<!-- 日期选择器 -->
<el-form-item
v-else-if="item.type === 'date'"
:label="item.label"
:prop="item.prop"
>
<el-date-picker
v-model="formModel[item.prop]"
:type="item.dateType || 'date'"
:placeholder="item.placeholder || `请选择${item.label}`"
:value-format="item.valueFormat || 'yyyy-MM-dd'"
clearable
/>
</el-form-item>
<!-- 日期范围选择器 -->
<el-form-item
v-else-if="item.type === 'daterange'"
:label="item.label"
:prop="item.prop"
>
<el-date-picker
v-model="formModel[item.prop]"
type="daterange"
:start-placeholder="item.startPlaceholder || '开始日期'"
:end-placeholder="item.endPlaceholder || '结束日期'"
:value-format="item.valueFormat || 'yyyy-MM-dd'"
clearable
/>
</el-form-item>
<!-- 自定义插槽 -->
<el-form-item
v-else-if="item.type === 'slot'"
:label="item.label"
:prop="item.prop"
>
<slot :name="item.slotName" :form="formModel"></slot>
</el-form-item>
</template>
<!-- 操作按钮区域 -->
<el-form-item class="search-form-actions">
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
<slot name="extra-actions"></slot>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: 'SearchForm',
props: {
// 表单配置项
formItems: {
type: Array,
required: true,
validator: (value) => {
return value.every((item) => {
return item.prop && item.label
})
}
},
// 初始值
initialValues: {
type: Object,
default: () => ({})
},
// 标签宽度
labelWidth: {
type: String,
default: '100px'
}
},
data() {
return {
formModel: {}
}
},
watch: {
initialValues: {
immediate: true,
handler(val) {
this.initFormModel(val)
}
}
},
methods: {
// 初始化表单数据
initFormModel(initialValues) {
const defaultModel = {}
this.formItems.forEach((item) => {
defaultModel[item.prop] = initialValues[item.prop] ?? null
})
this.formModel = defaultModel
},
// 搜索事件
handleSearch() {
this.$emit('search', this.formModel)
},
// 重置表单
handleReset() {
this.$refs.searchFormRef.resetFields()
this.$emit('reset')
},
// 获取表单数据
getFormData() {
return { ...this.formModel }
},
// 设置表单数据
setFormData(data) {
Object.keys(data).forEach((key) => {
if (this.formModel.hasOwnProperty(key)) {
this.formModel[key] = data[key]
}
})
}
}
}
</script>
<style lang="scss" scoped>
.search-form {
margin-bottom: 20px;
padding: 20px;
background: #f5f7fa;
border-radius: 4px;
&-actions {
float: right;
margin-right: 0;
}
}
</style>