<!-- QueryFilter.vue -->
<template>
<a-form
:model="model"
layout="inline"
class="form"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
>
<a-row :gutter="gutter">
<a-col v-for="(item, index) in itemsSearch" :key="index" :span="item.span || 6">
<a-form-item :colon="item.colon ? false : true">
<template #label>
<span>
<a-tooltip :overlayStyle="{ maxWidth: '500px' }">
<template #title>
<div v-if="Array.isArray(item.tips)">
<div v-for="subitem in item.tips">{{ subitem }}</div>
</div>
<div v-else>{{ item.tips }}</div>
</template>
<InfoCircleOutlined v-if="item.tips" />
</a-tooltip>
{{ item.label }}
</span>
</template>
<component
:is="item.component"
style="width: 100%"
v-bind="item.props || {}"
v-model:value="model[item.field]"
:placeholder="item.placeholder || `请输入${item.label}`"
/>
</a-form-item>
</a-col>
<a-col :span="getSpan()">
<span class="btn-wrapper">
<a-form-item :label-col="{ span: 0 }" :wrapper-col="{ span: 24 }">
<slot name="actions">
<a-button
style="margin-left: 8px"
:icon="h(SwapOutlined)"
@click="$emit('reset')"
>重置</a-button
>
<a-button type="primary" :icon="h(SearchOutlined)" @click="$emit('search')"
>查询</a-button
>
</slot>
</a-form-item>
</span>
</a-col>
</a-row>
</a-form>
<div class="collapsed" @click="onDown" v-if="collapsed">展开更多<DownOutlined /></div>
<div class="collapsed" @click="onUp" v-if="!collapsed">收起更多<UpOutlined /></div>
</template>
<script lang="ts" setup>
import { h, nextTick, ref } from 'vue';
import {
SearchOutlined,
SwapOutlined,
DownOutlined,
UpOutlined,
InfoCircleOutlined,
} from '@ant-design/icons-vue';
const props: any = defineProps({
model: {
type: Object,
required: true,
},
items: {
type: Array,
required: true,
},
gutter: {
type: Object,
default: { xs: 8, sm: 16, md: 24, lg: 32 },
},
actionSpan: {
type: Number,
default: 6,
},
updateHeight: {
type: Function,
},
});
/**
* 展开更多
*/
const collapsed = ref(true);
const itemsSearch: any = ref(props.items.slice(0, 3));
// 展开更多
const onDown = () => {
collapsed.value = !collapsed.value;
itemsSearch.value = props.items;
nextTick(() => {
props.updateHeight();
});
};
// 收起更多
const onUp = () => {
collapsed.value = !collapsed.value;
itemsSearch.value = props.items.slice(0, 3);
nextTick(() => {
props.updateHeight();
});
};
const getSpan = () => {
if (itemsSearch.value.length % 3 === 0) {
return 24;
} else if (itemsSearch.value.length % 3 === 1) {
return 16;
} else if (itemsSearch.value.length % 3 === 2) {
return 8;
}
};
</script>
<style lang="less" scoped>
.form {
width: 100% !important;
.btn-wrapper {
width: 100%;
text-align: right;
.a-btn-primary {
margin-left: 16px;
}
}
.a-col {
margin-bottom: 16px;
}
}
</style>
使用方式
<CommonForm
:items="columns"
:model="form"
@search="onSearch"
@reset="onReset"
:updateHeight="updateHeight"
/>
// 查询的列
const columns: any = reactive([
{
label: 'xxx',
field: 'xxx',
component: 'a-tree-select',
span: 8,
props: {
treeData: [],
'allow-clear': true,
showSearch: true,
treeNodeFilterProp: 'label',
'field-names': {
label: 'label',
value: 'id',
children: 'children',
},
},
},
{
label: 'xxx',
field: 'xxx',
component: 'a-input',
span: 8,
},
{
label: `xxx`,
field: 'xxx',
component: 'a-range-picker',
span: 8,
placeholder: ['开始时间', '结束时间'],
props: {
'value-format': 'YYYY-MM-DD',
},
// 图标前放个提示图标,tips内是提示内容
tips: [
'xxx',
'xxx',
],
},
{
label: 'xxx',
field: 'xxx',
component: 'a-select',
placeholder: 'xxx',
span: 8,
props: {
allowClear: true,
options: dictData.value?.sjly,
},
},
{
label: 'xxx',
field: 'xxx',
component: 'a-cascader',
span: 8,
props: {
options: [],
'allow-clear': true,
'tree-node-filter-prop': 'label',
'field-names': {
label: 'label',
value: 'id',
children: 'childs',
},
},
}
]);
// 点击展开收起之后更新table高
const updateHeight = () => {}
// 查询
const onSearch = () => {}
// 重置
const onReset = () => {}