<!-- src/components/FilterPanel.vue -->
|
<template>
|
<el-card class="filter-panel">
|
<el-form :inline="true" :model="formData" class="filter-form" label-width="80px">
|
<!-- 动态渲染表单字段 -->
|
<template v-for="field in fields">
|
<!-- 下拉选择(单选) -->
|
<el-form-item
|
v-if="field.type === 'select' && !field.multiple"
|
:key="field.prop"
|
:label="field.label"
|
>
|
<el-select
|
v-model="formData[field.prop]"
|
:placeholder="field.placeholder || `请选择${field.label}`"
|
clearable
|
:style="{ width: field.width || '200px' }"
|
>
|
<el-option
|
v-for="item in field.options"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
|
<!-- 下拉选择(多选) -->
|
<el-form-item
|
v-if="field.type === 'select' && field.multiple"
|
:key="field.prop"
|
:label="field.label"
|
>
|
<el-select
|
v-model="formData[field.prop]"
|
:placeholder="field.placeholder || `请选择${field.label}`"
|
clearable
|
multiple
|
collapse-tags
|
:style="{ width: field.width || '300px' }"
|
>
|
<el-option
|
v-for="item in field.options"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
|
<!-- 日期范围选择 -->
|
<el-form-item
|
v-if="field.type === 'daterange'"
|
:key="field.prop"
|
:label="field.label"
|
>
|
<el-date-picker
|
v-model="formData[field.prop]"
|
:type="field.dateType || 'daterange'"
|
:range-separator="field.rangeSeparator || '至'"
|
:start-placeholder="field.startPlaceholder || '开始日期'"
|
:end-placeholder="field.endPlaceholder || '结束日期'"
|
:value-format="field.valueFormat || 'yyyy-MM-dd'"
|
:style="{ width: field.width || '300px' }"
|
/>
|
</el-form-item>
|
|
<!-- 输入框 -->
|
<el-form-item
|
v-if="field.type === 'input'"
|
:key="field.prop"
|
:label="field.label"
|
>
|
<el-input
|
v-model="formData[field.prop]"
|
:placeholder="field.placeholder || `请输入${field.label}`"
|
clearable
|
:style="{ width: field.width || '200px' }"
|
@keyup.enter.native="handleSearch"
|
/>
|
</el-form-item>
|
|
<!-- 自定义插槽 -->
|
<el-form-item
|
v-if="field.type === 'slot'"
|
:key="field.prop"
|
:label="field.label"
|
>
|
<slot :name="field.slotName"></slot>
|
</el-form-item>
|
</template>
|
|
<!-- 操作按钮 -->
|
<el-form-item class="filter-actions">
|
<el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button>
|
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
<slot name="extra-actions"></slot>
|
</el-form-item>
|
</el-form>
|
</el-card>
|
</template>
|
|
<script>
|
export default {
|
name: 'FilterPanel',
|
props: {
|
// 表单字段配置
|
fields: {
|
type: Array,
|
default: () => []
|
},
|
// 表单默认值
|
defaultValue: {
|
type: Object,
|
default: () => ({})
|
}
|
},
|
data() {
|
return {
|
formData: { ...this.defaultValue }
|
};
|
},
|
watch: {
|
defaultValue: {
|
deep: true,
|
handler(newVal) {
|
this.formData = { ...newVal };
|
}
|
}
|
},
|
methods: {
|
handleSearch() {
|
this.$emit('search', this.formData);
|
},
|
handleReset() {
|
this.formData = { ...this.defaultValue };
|
this.$emit('reset', this.formData);
|
},
|
// 暴露给父组件的方法
|
getFormData() {
|
return { ...this.formData };
|
},
|
setFormData(data) {
|
this.formData = { ...data };
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.filter-panel {
|
margin-bottom: 20px;
|
}
|
|
.filter-form {
|
margin-bottom: 0;
|
}
|
|
.filter-actions {
|
float: right;
|
margin-right: 0;
|
margin-bottom: 0;
|
}
|
</style>
|