UNIVPLMDataIntegration/Web/src/components/table/search.vue

245 lines
7.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="table-search-container" v-if="props.search.length > 0">
<el-form ref="tableSearchRef" :model="state.innerModelValue" @submit.native.prevent label-width="100px" class="table-form">
<el-row :gutter="10">
<!-- <el-col :xs="12" :sm="8" :md="8" :lg="6" :xl="4" class="mb20"></el-col> -->
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-for="(val, key) in search" :key="key" v-show="key < 4 || state.isToggle">
<template v-if="val.type">
<el-form-item
label-width="auto"
:label="val.label"
:prop="val.prop"
:rules="[{ required: val.required, message: `${val.label}${t('message.list.required')}`, trigger: val.type === 'input' ? 'blur' : 'change' }]"
>
<el-input
v-model="state.innerModelValue[val.prop]"
v-bind="val.comProps"
:placeholder="val.placeholder"
:clearable="!val.required"
v-if="val.type === 'input'"
@keyup.enter="onSearch(tableSearchRef)"
@change="val.change"
class="w100"
/>
<el-date-picker
v-model="state.innerModelValue[val.prop]"
v-bind="val.comProps"
type="date"
:placeholder="val.placeholder"
:clearable="!val.required"
v-else-if="val.type === 'date'"
@change="val.change"
class="w100"
/>
<el-date-picker
v-model="state.innerModelValue[val.prop]"
v-bind="val.comProps"
type="monthrange"
:placeholder="val.placeholder"
:clearable="!val.required"
v-else-if="val.type === 'monthrange'"
@change="val.change"
class="w100"
/>
<el-date-picker
v-model="state.innerModelValue[val.prop]"
v-bind="val.comProps"
type="daterange"
:range-separator="t('message.list.to')"
:start-placeholder="t('message.list.startDate')"
:end-placeholder="t('message.list.endDate')"
:clearable="!val.required"
:shortcuts="shortcuts"
:default-time="defaultTime"
v-else-if="val.type === 'daterange'"
@change="val.change"
class="w100"
/>
<el-select
v-model="state.innerModelValue[val.prop]"
v-bind="val.comProps"
:clearable="!val.required"
filterable
:placeholder="val.placeholder"
v-else-if="val.type === 'select'"
@change="val.change"
class="w100"
>
<el-option v-for="item in val.options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
<el-cascader
v-else-if="val.type === 'cascader' && val.cascaderData"
:options="val.cascaderData"
:clearable="!val.required"
filterable
:props="val.cascaderProps ? val.cascaderProps : state.cascaderProps"
:placeholder="val.placeholder"
@change="val.change"
class="w100"
v-bind="val.comProps"
v-model="state.innerModelValue[val.prop]"
>
</el-cascader>
</el-form-item>
</template>
</el-col>
<el-col v-if="false" :xs="12" :sm="9" :md="9" :lg="6" :xl="4" class="mb20">
<el-form-item class="table-form-btn" label-width="auto">
<div>
<!-- 使用el-button-group会导致具有type属性的按钮的右边框无法显示 -->
<!-- <el-button-group> -->
<el-button plain type="primary" icon="ele-Search" @click="onSearch(tableSearchRef)"> {{ t('message.list.query') }} </el-button>
<el-button icon="ele-Refresh" @click="onReset(tableSearchRef)" style="margin-left: 12px"> {{ t('message.list.reset') }} </el-button>
<!-- </el-button-group> -->
</div>
</el-form-item>
</el-col>
</el-row>
<!-- <el-divider style="margin-top: 5px" v-if="search.length > 3">
<el-button :icon="state.isToggle ? 'ele-ArrowUpBold' : 'ele-ArrowDownBold'" class="divider-btn" @click="state.isToggle = !state.isToggle"> </el-button>
</el-divider> -->
</el-form>
<el-row>
<el-col>
<el-button v-if="search.length > 4" class="table-btn-toggle" type="primary" text bg @click="state.isToggle = !state.isToggle">
<SvgIcon :name="state.isToggle ? 'ele-ArrowUp' : 'ele-ArrowDown'" />
</el-button>
<div v-else style="width: 4px; display: inline-block" />
<el-button-group>
<el-button type="primary" icon="ele-Search" @click="onSearch(tableSearchRef)"> {{ t('message.list.query') }} </el-button>
<el-button icon="ele-Refresh" @click="onReset(tableSearchRef)"> {{ t('message.list.reset') }} </el-button>
</el-button-group>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts" name="makeTableDemoSearch">
import { reactive, ref, watch } from 'vue';
import type { FormInstance } from 'element-plus';
import { dayjs } from 'element-plus';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
// 定义父组件传过来的值
const props = defineProps({
// 搜索表单,type-控件类型input,select,cascader,date,options-type为selct时需传值cascaderData,cascaderProps-type为cascader时需传值属性同elementUI,cascaderProps不传则使用state默认。
// 可带入comProps属性和使用的控件属性对应
search: {
type: Array<TableSearchType>,
default: () => [],
},
modelValue: {
type: Object,
default: () => ({}),
},
});
// 定义子组件向父组件传值/事件
const emit = defineEmits(['search', 'reset', 'update:modelValue']);
// 定义变量内容
const tableSearchRef = ref<FormInstance>();
const state = reactive({
isToggle: false,
cascaderProps: { checkStrictly: true, emitPath: false, value: 'id', label: 'name', expandTrigger: 'hover' },
/** 内部 modelValue */
innerModelValue: {} as EmptyObjectType,
});
/** 监听 props.modelValue 变化 */
watch(
() => props.modelValue,
(val) => {
state.innerModelValue = val;
},
{ immediate: true }
);
/** 监听 state.innerModelValue 变化 */
watch(
() => state.innerModelValue,
(val) => {
emit('update:modelValue', val);
},
{ deep: true }
);
// 查询
const onSearch = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate((isValid: boolean): void => {
if (!isValid) return;
emit('search', state.innerModelValue);
});
};
// 重置
const onReset = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
emit('reset', state.innerModelValue);
};
/** 时间范围默认时间 */
const defaultTime = ref<[Date, Date]>([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]);
/** 时间范围快捷选择 */
const shortcuts = [
{
text: t('message.list.last7Days'),
value: () => {
const end = dayjs().endOf('day').toDate();
const start = dayjs().startOf('day').add(-7, 'day').toDate();
return [start, end];
},
},
{
text: t('message.list.lastMonth'),
value: () => {
const end = dayjs().endOf('day').toDate();
const start = dayjs().startOf('day').add(-1, 'month').toDate();
return [start, end];
},
},
{
text: t('message.list.last3Months'),
value: () => {
const end = dayjs().endOf('day').toDate();
const start = dayjs().startOf('day').add(-3, 'month').toDate();
return [start, end];
},
},
];
</script>
<style scoped lang="scss">
.table-search-container {
display: flex;
.table-form {
flex: 1;
.table-form-btn-toggle {
white-space: nowrap;
user-select: none;
display: flex;
align-items: center;
color: var(--el-color-primary);
}
}
}
.divider-btn {
height: 20px;
border-radius: 10px;
}
.table-btn-toggle {
margin: 0 4px;
padding: 0 2px;
}
</style>