1.项目中有个页面客户提到使用高级搜索,需要仿照jeecgboot3的高级搜索框,(下载的代码里面没有这个组件,应该是要收费,所以只好自己看人家的效果,然后自己手动封装一个)即左侧的条件为从表格的表头动态获取,中间的方式为等于/模糊,右侧的输入框为查询内容,点即最右侧的 + 可以新增一列,点击最右侧的 - 删除一列,若是条件都删除,通过新增按钮,在新增一列,后来客户又提了新的需求,说是要加个筛选条件关系,如 并且(多个条件必须同时满足) 和 或(多个条件,有一个满足就行)
高级搜索组件代码
advancedQuery.vue
<template>
<a-modal v-model:visible="props.visibleSearch" title="高级查询" @ok="handleOk" :width="700" @cancel="handleCancel">
<template #footer>
<div style="display: flex; justify-content: space-between">
<span>
<a-button key="reset" @click="resetSearch">重置</a-button>
<a-button key="save" @click="saveSearch">保存查询</a-button>
</span>
<span>
<a-button key="back" @click="handleCancel">关闭</a-button>
<a-button key="submit" type="primary" @click="confirm">确定</a-button>
</span>
</div>
</template>
<div style="display: flex; justify-content:flex-start;margin-top:10px;padding:0 20px;align-items:center;">
<div style="margin-right:10px;">筛选条件并列关系:</div>
<div>
<a-select v-model:value="relation" placeholder="请选择关系" allowClear style="width: 160px">
<a-select-option v-for="(item, index) in relationData" :key="index" :label="item.text" :value="item.value">{{ item.text }}</a-select-option>
</a-select>
</div>
</div>
<div style="min-height: 200px" v-if="childList.length > 0">
<div style="margin: 20px" v-for="(item, index) in childList" :key="index">
<a-select v-model:value="item.field" placeholder="请选择字段" allowClear style="width: 160px; margin-right: 10px">
<a-select-option v-for="(item, index) in props.fieldData" :key="index" :label="item.title" :value="item.key">{{
item.title
}}</a-select-option>
</a-select>
<a-select v-model:value="item.condition" placeholder="请选择" allowClear style="width: 120px; margin-right: 10px">
<a-select-option v-for="(item, index) in props.filedCondition" :key="index" :label="item.text" :value="item.value">{{
item.text
}}</a-select-option>
</a-select>
<a-input v-model:value="item.fieldValue" style="width: 120px; margin-right: 10px"></a-input>
<a-button style="margin-right: 10px" @click="addRowCustom"><Icon icon="ant-design:plus-outlined"></Icon></a-button>
<a-button @click="delRowCustom(index)"><Icon icon="ant-design:minus-circle-outlined"></Icon></a-button>
</div>
</div>
<div v-else style="min-height: 200px">
<a-empty />
<div style="display: flex; justify-content: center; align-items: center"
>没有任何查询条件 <a-divider type="vertical" /> <span style="color: #3e90ff; cursor: pointer" @click="addRowCustom">点击新增</span></div
>
</div>
</a-modal>
</template>
<script lang="ts" setup>
import { computed, reactive, ref, defineEmits, defineProps } from 'vue';
const emits = defineEmits(['close', 'reset', 'confirm']);
// const resetEmits=defineEmits(['reset'])
const props = defineProps({
fieldData: {
type: Array,
default: [],
}, //字段
visibleSearch: {
type: Boolean,
default: false,
},
// Boolean,//条件
filedCondition: {
type: Array,
default: [],
}, //值
relation: {
type: Number,
default: 0,
},
});
const relation=ref(0);
// relation.value=props.relation;
const relationData = [
{ value: 0, text: 'or' },
{ value: 1, text: 'and' },
];
const visible = ref(false);
visible.value = props.visibleSearch;
let childList = ref([{}]);
function addRowCustom() {
childList.value.push({});
}
function delRowCustom(index) {
childList.value.splice(index, 1);
}
function confirm() {
let obj={
childList:childList.value,
relation:relation.value,
}
console.log(childList.value, 'childList++');
emits('confirm', obj);
}
function resetSearch() {
// console.log("重置按钮")
const obj = '';
relation.value=0;
childList.value = [{}];
emits('reset', obj);
}
function saveSearch() {
console.log('保存按钮');
}
function handleCancel() {
const obj = ref({
visible: false,
});
emits('close', obj);
}
</script>
使用高级搜索组件
html部分
<advancedQuery
@close="handleCancel"
@reset="resetSearch"
@confirm="handleOk"
:fieldData="columns"
:filedCondition="conditionData"
:visibleSearch="visible"
></advancedQuery>
js部分
import advancedQuery from '/@/components/advancedQuery.vue'; //引入高级查询组件
const dataSource=ref([]);
const columns = [
{
title: '数量',
dataIndex: 'qty',
key: 'qty',
align: 'center',
ellipsis: true,
width: 80,
},
{
title: '供应商编码',
dataIndex: 'vendorCode',
key: 'vendorCode',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '产品名称',
dataIndex: 'productName',
key: 'productName',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '物料编号',
dataIndex: 'productCode',
key: 'productCode',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '产品上级名称',
dataIndex: 'productParent',
key: 'productParent',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '产品上级图号',
dataIndex: 'productParentFig',
key: 'productParentFig',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '产品下级',
dataIndex: 'productChild',
key: 'productChild',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '产品状态',
dataIndex: 'productState',
key: 'productState',
align: 'center',
ellipsis: true,
width: 120,
},
{
title: '材质',
dataIndex: 'material',
key: 'material',
align: 'center',
ellipsis: true,
width: 100,
},
{
title: '表面处理',
dataIndex: 'surfaceDeal',
key: 'surfaceDeal',
align: 'center',
ellipsis: true,
width: 100,
},
{
title: '热处理',
dataIndex: 'headDeal',
key: 'headDeal',
align: 'center',
ellipsis: true,
width: 100,
},
{
title: '技术编号',
dataIndex: 'techNo',
key: 'techNo',
align: 'center',
ellipsis: true,
width: 100,
},
{
title: '备注',
dataIndex: 'remark',
key: 'remark',
align: 'center',
ellipsis: true,
width: 100,
},
];
const visible = ref(false);
const relation = ref(0);
const conditionArr = ref([]); //查询条件
const conditionData = ref();
conditionData.value = [
{ value: 1, text: '等于' },
{ value: 2, text: '模糊' },
// { value: 3, text: '以..开始' },
// { value: 4, text: '以..结尾' },
// { value: 5, text: '在...中' },
// { value: 6, text: '不等于' },
// { value: 7, text: '大于' },
// { value: 8, text: '大于等于' },
];
function advancedSearch() {
visible.value = true;
}
function handleOk(obj) {
console.log(obj, '组件传值');
let arr = obj.childList;
relation.value = obj.relation;
if (JSON.stringify(arr[0]) == '{}') {
conditionArr.value = [];
} else {
conditionArr.value = arr;
}
visible.value = false;
let inData = JSON.parse(sessionStorage.getItem('inData'));
if (inData) {
dataSource.value = inData;
}
let temp = inData;
if(relation.value==0){
let temp3 = [];
if(conditionArr.value.length>0){
for (let item of dataSource.value) {
for (let j of conditionArr.value) {
if (j.condition == 1) {
if (item[j.field] == j.fieldValue) {
temp3.push(item)
}
} else if (j.condition == 2) {
if (item[j.field].toString().indexOf(j.fieldValue) != -1) {
temp3.push(item);
}
}
}
}
dataSource.value = reduce(temp3, 'productCode');
}
}else if(relation.value==1){
for (let i = 0; i < conditionArr.value.length; i++) {
let temp2 = [];
for (let j = 0; j < temp.length; j++) {
if (conditionArr.value[i].condition == 1) {
if (temp[j][conditionArr.value[i].field] == conditionArr.value[i].fieldValue) {
temp2.push(temp[j]);
}
}
if (conditionArr.value[i].condition == 2) {
if (temp[j][conditionArr.value[i].field].toString().indexOf(conditionArr.value[i].fieldValue.toString()) != -1) {
temp2.push(temp[j]);
}
}
}
let mixed = [];
temp.forEach((item) => {
temp2.forEach((items) => {
if (item.productCode == items.productCode) {
mixed.push(item);
}
});
});
temp = mixed;
}
dataSource.value=temp;
}
console.log(dataSource.value,'dataSource++')
}
function resetSearch() {
relation.value = 0;
conditionArr.value = [];
}
function saveSearch() {
console.log('保存按钮');
}
function handleCancel() {
visible.value = false;
}