<template>
<el-form ref="formRef" :model="getModelValue" :rules="rules" inline>
<el-form-item
v-for="item in formItems"
:prop="item.field"
:label="item.label"
>
<el-select
v-if="item.compName === 'ElSelect'"
v-bind="item.props"
v-model="getModelValue[item.field]"
filterable
fit-input-width
:clearable="!!(item.props?.clearable !== false)"
>
<el-option
v-for="(oItem, index) in getPropsKeyValue(item, 'options')"
:label="oItem[getPropsKeyValue(item)]"
:value="oItem[getPropsKeyValue(item, 'value')]"
:key="index"
>
<newToolTip
:enterable="false"
placement="top"
:rows="1"
:content="oItem[getPropsKeyValue(item)]"
>{{ oItem[getPropsKeyValue(item)] }}</newToolTip
>
</el-option></el-select
>
<component
v-else-if="item.compName"
v-bind="item.props"
:clearable="item.props?.clearable !== false"
v-model="getModelValue[item.field]"
:is="item.compName"
></component>
<template v-else>
<el-input
v-model="getModelValue[item.field]"
v-bind="item.props"
:clearable="item.props?.clearable !== false"
:placeholder="item.props?.placeholder || '请输入'"
v-show="!$slots?.[item.field]"
></el-input>
<slot :name="item.field" :item="item"></slot>
</template>
</el-form-item>
<el-form-item v-if="isBtns">
<el-button
type="primary"
:disabled="getDisabled('submit')"
v-baseDebounceClick
@click="search"
>查询</el-button
>
<el-button
plain
type="primary"
:disabled="getDisabled('reset')"
v-baseDebounceClick
@click="reset"
>重置</el-button
>
</el-form-item>
</el-form>
</template>
<script>
import { ElDatePicker, ElSelect } from 'element-plus';
import newToolTip from './newToolTip.vue';
export default {
components: {
newToolTip,
ElDatePicker,
ElSelect,
},
props: {
modelValue: {
type: Object,
default: () => ({}),
},
formItems: {
type: Array,
default: () => [],
},
isBtns: {
type: Boolean,
default: true,
},
},
emits: ['search', 'query', 'reset', 'update:modelValue', 'change'],
data() {
return {};
},
computed: {
rules() {
return this.formItems.reduce((prev, current) => {
if (current?.field && current?.rules) {
const newCurrent = prev;
newCurrent[current.field] = current.rules;
return newCurrent;
}
return prev;
}, {});
},
getDefaultValue() {
return this.formItems.map(({ defaultValue }) => defaultValue);
},
getRequiredAllValue() {
return this.formItems
.filter(({ required }) => required)
.map(({ field }) => field)
.every(
(key) =>
this.getModelValue[key] ||
[0, false].includes(this.getModelValue[key])
);
},
getModelValue: {
get() {
return new Proxy(this.modelValue, {
get: (target, field) => Reflect.get(target, field),
set: (target, field, value) => {
this.updateFieldValue(field, value);
return true;
},
});
},
},
},
methods: {
updateFieldValue(field, value) {
const target = this.modelValue;
if (target[field] !== value) {
this.$emit('change', { field, value });
target[field] = value;
this.$emit('update:modelValue', { ...target });
}
},
getPropsKeyValue(item, key = 'label') {
return item?.props?.[key] || key;
},
initModelValue() {
this.formItems
.filter((item) => 'defaultValue' in item)
.map((item) => {
if (
!(item.field in this.getModelValue) ||
this.getModelValue[item.field] !== item.defaultValue
) {
this.getModelValue[item.field] = item.defaultValue;
}
});
},
emits(list) {
list.map((key) => {
this.$emit(key, JSON.parse(JSON.stringify(this.getModelValue)));
});
},
search() {
if (!this.getDisabled('submit')) {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.emits(['search', 'query']);
}
});
}
},
reset() {
this.initModelValue();
this.emits(['reset', 'query']);
},
getDisabled(type) {
return !this.getRequiredAllValue;
},
},
watch: {
getDefaultValue: {
handler(newVal) {
this.initModelValue();
},
deep: true,
immediate: true,
},
},
};
</script>
/*
使用说明:
<sPSearch
ref="sPSearchRef"
v-model="searchForm"
:formItems="formItems"
@search="search"
@reset="query"
@change="change"
/>
methods: {
search(val) {
console.error('search-', val, '-search ', this.searchForm);
},
query(val) {
console.error('reset-', val, '-reset ', this.searchForm);
},
change(val) {
console.error('change', val);
if (val?.field === 'dataDate') {
//如果需要在dataDate改变时,手动改变securitySituation的值
// 此处特别注意:不能直接使用this.searchForm.securitySituation='-1';
// 这样直接在外层改变赋值会导致change事件无法触发
this.$refs.sPSearchRef?.updateFieldValue('securitySituation', '-1');
}
}
}
*/
console