|
@@ -1,171 +1,153 @@
|
|
|
-
|
|
|
|
|
<!-- 需要配合 page_search search_content content_left 一起使用 -->
|
|
<!-- 需要配合 page_search search_content content_left 一起使用 -->
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
<template>
|
|
<template>
|
|
|
<div class="simple_filter">
|
|
<div class="simple_filter">
|
|
|
<template v-for="item in props.searchList" :key="item.key">
|
|
<template v-for="item in props.searchList" :key="item.key">
|
|
|
- <el-select
|
|
|
|
|
- v-if="item.type == 'select' && !item.hidden"
|
|
|
|
|
- v-model="searchData[item.key]"
|
|
|
|
|
- @change="(val)=>HandleSearchItemChange(item.key)"
|
|
|
|
|
- :placeholder="item.placeholder"
|
|
|
|
|
- :disabled="formDisabled || item.disabled"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="optItm in item.options"
|
|
|
|
|
- :key="optItm.value" :value="optItm.value"
|
|
|
|
|
- :label="optItm.label"
|
|
|
|
|
- :disabled="optItm.disabled ? true : false">
|
|
|
|
|
|
|
+ <div class="filter_item">
|
|
|
|
|
+ <div v-if="item.label" class="filter_label">{{ item.label }}:</div>
|
|
|
|
|
+ <el-select v-if="item.type == 'select' && !item.hidden" v-model="searchData[item.key]"
|
|
|
|
|
+ @change="() => HandleSearchItemChange(item.key)" :placeholder="item.placeholder"
|
|
|
|
|
+ :disabled="formDisabled || item.disabled" :filterable="item.filterable === true"
|
|
|
|
|
+ :clearable="item.clearable === true">
|
|
|
|
|
+ <el-option v-for="optItm in item.options" :key="optItm.value" :value="optItm.value"
|
|
|
|
|
+ :label="optItm.label" :disabled="optItm.disabled ? true : false">
|
|
|
</el-option>
|
|
</el-option>
|
|
|
</el-select>
|
|
</el-select>
|
|
|
|
|
|
|
|
|
|
+ <el-date-picker @change="() => HandleSearchItemChange(item.key)" v-else-if="item.type == 'datePicker'"
|
|
|
|
|
+ v-model="searchData[item.key]" :disabled="formDisabled || item.disabled" type="daterange"
|
|
|
|
|
+ range-separator="-" start-placeholder="开始时间" end-placeholder="结束时间" />
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- <!-- :size="size" -->
|
|
|
|
|
- <el-date-picker
|
|
|
|
|
- @change="(val)=>HandleSearchItemChange(item.key)"
|
|
|
|
|
- v-else-if="item.type == 'datePicker'"
|
|
|
|
|
- v-model="searchData[item.key]"
|
|
|
|
|
- :disabeld="formDisabled || item.disabled"
|
|
|
|
|
- type="daterange"
|
|
|
|
|
- range-separator="-"
|
|
|
|
|
- start-placeholder="开始时间"
|
|
|
|
|
- end-placeholder="结束时间"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- <!-- 这个输入框的搜索要动态查询 ———— -->
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-else-if="item.type == 'input'"
|
|
|
|
|
- v-model="searchData[item.key]"
|
|
|
|
|
-
|
|
|
|
|
- @input="(val,e)=>HandleInputChange(val,e,item.key)"
|
|
|
|
|
-
|
|
|
|
|
- @keyup.enter="(event)=>HandleSearchItemChange(item.key)"
|
|
|
|
|
- :placeholder="item.placeholder"
|
|
|
|
|
- :disabled="formDisabled || item.disabled"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-input v-else-if="item.type == 'input'" v-model="searchData[item.key]"
|
|
|
|
|
+ @input="(val: any) => HandleInputChange(val, item.key)" @keyup.enter="() => HandleSearchItemChange(item.key)"
|
|
|
|
|
+ :placeholder="item.placeholder" :disabled="formDisabled || item.disabled">
|
|
|
<template #append>
|
|
<template #append>
|
|
|
<el-button @click="HandleSearchItemChange(item.key)" :icon="Search" />
|
|
<el-button @click="HandleSearchItemChange(item.key)" :icon="Search" />
|
|
|
- </template>
|
|
|
|
|
|
|
+ </template>
|
|
|
</el-input>
|
|
</el-input>
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- <el-radio-group
|
|
|
|
|
- v-else-if="item.type == 'radio'"
|
|
|
|
|
- v-model="searchData[item.key]"
|
|
|
|
|
- @change="()=>HandleSearchItemChange(item.key)"
|
|
|
|
|
- :disabled="formDisabled || item.disabled"
|
|
|
|
|
- >
|
|
|
|
|
- <el-radio v-for="radioItem in item.options" :key="radioItem.value" :value="radioItem.value">{{ radioItem.label }}</el-radio>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <el-radio-group v-else-if="item.type == 'radio'" v-model="searchData[item.key]"
|
|
|
|
|
+ @change="() => HandleSearchItemChange(item.key)" :disabled="formDisabled || item.disabled">
|
|
|
|
|
+ <el-radio v-for="radioItem in item.options" :key="radioItem.value" :value="radioItem.value">{{
|
|
|
|
|
+ radioItem.label
|
|
|
|
|
+ }}</el-radio>
|
|
|
</el-radio-group>
|
|
</el-radio-group>
|
|
|
|
|
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import { Search } from '@element-plus/icons-vue'
|
|
import { Search } from '@element-plus/icons-vue'
|
|
|
|
|
+import type { PropType } from 'vue'
|
|
|
|
|
|
|
|
import { ref, watch } from 'vue'
|
|
import { ref, watch } from 'vue'
|
|
|
|
|
|
|
|
interface SearchItem {
|
|
interface SearchItem {
|
|
|
- key:String,
|
|
|
|
|
- type:'input'|'select'|'datePicker'|'radio',
|
|
|
|
|
- placeholder?:String,
|
|
|
|
|
- hidden:boolean,
|
|
|
|
|
- defaultValue?:any,
|
|
|
|
|
- disabled?:Boolean
|
|
|
|
|
- options?:{
|
|
|
|
|
- label:String,
|
|
|
|
|
- value:String,
|
|
|
|
|
- disabled?:Boolean
|
|
|
|
|
- }[]
|
|
|
|
|
|
|
+ key: string,
|
|
|
|
|
+ type: 'input' | 'select' | 'datePicker' | 'radio',
|
|
|
|
|
+ label?: string,
|
|
|
|
|
+ placeholder?: string,
|
|
|
|
|
+ hidden: boolean,
|
|
|
|
|
+ defaultValue?: any,
|
|
|
|
|
+ disabled?: boolean,
|
|
|
|
|
+ filterable?: boolean,
|
|
|
|
|
+ clearable?: boolean,
|
|
|
|
|
+ options?: {
|
|
|
|
|
+ label: string,
|
|
|
|
|
+ value: string | number,
|
|
|
|
|
+ disabled?: boolean
|
|
|
|
|
+ }[]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
|
- searchList:{
|
|
|
|
|
- type:Array<SearchItem>,
|
|
|
|
|
- required:true
|
|
|
|
|
|
|
+ searchList: {
|
|
|
|
|
+ type: Array as PropType<SearchItem[]>,
|
|
|
|
|
+ required: true
|
|
|
},
|
|
},
|
|
|
- formDisabled:{
|
|
|
|
|
- type:Boolean,
|
|
|
|
|
- required:false
|
|
|
|
|
|
|
+ formDisabled: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ required: false
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-const emit = defineEmits(['searchChange'])
|
|
|
|
|
|
|
+const emit = defineEmits<{
|
|
|
|
|
+ (e: 'searchChange', data: Record<string, any>, key: string): void
|
|
|
|
|
+}>()
|
|
|
|
|
|
|
|
-const searchData = ref({})
|
|
|
|
|
|
|
+const searchData = ref<Record<string, any>>({})
|
|
|
|
|
|
|
|
|
|
|
|
|
-// 筛选条件变更触发新的查询
|
|
|
|
|
-const HandleSearchItemChange = async (key)=>{
|
|
|
|
|
- // 触发父级页面的查询
|
|
|
|
|
- emit('searchChange',searchData.value,key)
|
|
|
|
|
|
|
+const HandleSearchItemChange = async (key: string) => {
|
|
|
|
|
+ emit('searchChange', searchData.value, key)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const inputFlag = ref()
|
|
|
|
|
|
|
+const inputFlag = ref<ReturnType<typeof setTimeout> | null>(null)
|
|
|
|
|
|
|
|
-const HandleInputChange = (val,e,key)=>{
|
|
|
|
|
- if(inputFlag.value){
|
|
|
|
|
- // 还在定时器内,延迟触发
|
|
|
|
|
|
|
+const HandleInputChange = (val: any, key: string) => {
|
|
|
|
|
+ if (inputFlag.value) {
|
|
|
clearTimeout(inputFlag.value)
|
|
clearTimeout(inputFlag.value)
|
|
|
- inputFlag.value = ''
|
|
|
|
|
}
|
|
}
|
|
|
- // 要防抖
|
|
|
|
|
- inputFlag.value = setTimeout(()=>{
|
|
|
|
|
- console.log('input__输入的值',val)
|
|
|
|
|
- // 触发父级页面的查询
|
|
|
|
|
- emit('searchChange',searchData.value,key)
|
|
|
|
|
- },400)
|
|
|
|
|
|
|
+ inputFlag.value = setTimeout(() => {
|
|
|
|
|
+ emit('searchChange', searchData.value, key)
|
|
|
|
|
+ }, 400)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
-//
|
|
|
|
|
-watch(()=>props.searchList, (newVal)=>{
|
|
|
|
|
|
|
+watch(() => props.searchList, (newVal: SearchItem[]) => {
|
|
|
searchData.value = {}
|
|
searchData.value = {}
|
|
|
- // console.log('查询项变更了===表单',newVal)
|
|
|
|
|
- newVal.forEach(item=>{
|
|
|
|
|
- if(item.defaultValue){
|
|
|
|
|
|
|
+ newVal.forEach(item => {
|
|
|
|
|
+ if (item.defaultValue !== undefined && item.defaultValue !== null) {
|
|
|
searchData.value[item.key] = item.defaultValue
|
|
searchData.value[item.key] = item.defaultValue
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
- // emit('searchChange',searchData.value)
|
|
|
|
|
-},{immediate:true,deep:true})
|
|
|
|
|
|
|
+}, { immediate: true, deep: true })
|
|
|
|
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
.simple_filter {
|
|
.simple_filter {
|
|
|
- display: flex;
|
|
|
|
|
- flex-wrap: wrap;
|
|
|
|
|
- gap: 10px;
|
|
|
|
|
-
|
|
|
|
|
- :deep(.el-date-editor){
|
|
|
|
|
- max-width: 240px;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- :deep(.el-input){
|
|
|
|
|
- width: 260px;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- :deep(.el-radio-group){
|
|
|
|
|
- .el-radio{
|
|
|
|
|
- margin-right: 20px;
|
|
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ // flex-wrap: wrap;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+
|
|
|
|
|
+ .filter_item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 5px;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .filter_label {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ color: #606266;
|
|
|
|
|
+ line-height: 32px;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-date-editor) {
|
|
|
|
|
+ max-width: 240px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-input) {
|
|
|
|
|
+ width: 260px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-radio-group) {
|
|
|
|
|
+ .el-radio {
|
|
|
|
|
+ margin-right: 20px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
-.page_search .search_content .content_right{
|
|
|
|
|
|
|
+.page_search .search_content .content_right {
|
|
|
.el-button {
|
|
.el-button {
|
|
|
margin-left: -20px !important;
|
|
margin-left: -20px !important;
|
|
|
min-width: auto !important;
|
|
min-width: auto !important;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-</style>
|
|
|
|
|
|
|
+</style>
|