feat
This commit is contained in:
136
src/components/search-form/index.vue
Normal file
136
src/components/search-form/index.vue
Normal file
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<a-row>
|
||||
<a-col :flex="1">
|
||||
<a-form
|
||||
:model="localModel"
|
||||
:label-col-props="{ span: 6 }"
|
||||
:wrapper-col-props="{ span: 18 }"
|
||||
label-align="left"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col v-for="item in formItems" :key="item.field" :span="item.span || 8">
|
||||
<a-form-item :field="item.field" :label="item.label">
|
||||
<!-- 输入框 -->
|
||||
<a-input
|
||||
v-if="item.type === 'input'"
|
||||
v-model="localModel[item.field]"
|
||||
:placeholder="item.placeholder"
|
||||
allow-clear
|
||||
/>
|
||||
<!-- 选择框 -->
|
||||
<a-select
|
||||
v-else-if="item.type === 'select'"
|
||||
v-model="localModel[item.field]"
|
||||
:options="item.options"
|
||||
:placeholder="item.placeholder || '请选择'"
|
||||
allow-clear
|
||||
/>
|
||||
<!-- 日期范围选择器 -->
|
||||
<a-range-picker
|
||||
v-else-if="item.type === 'dateRange'"
|
||||
v-model="localModel[item.field]"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-col>
|
||||
<a-divider v-if="showButtons" style="height: 84px" direction="vertical" />
|
||||
<a-col v-if="showButtons" :flex="'86px'" style="text-align: right">
|
||||
<a-space direction="vertical" :size="18">
|
||||
<a-button type="primary" @click="handleSearch">
|
||||
<template #icon>
|
||||
<icon-search />
|
||||
</template>
|
||||
{{ searchButtonText }}
|
||||
</a-button>
|
||||
<a-button @click="handleReset">
|
||||
<template #icon>
|
||||
<icon-refresh />
|
||||
</template>
|
||||
{{ resetButtonText }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { PropType, reactive, watch } from 'vue'
|
||||
import type { FormItem } from './types'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Object as PropType<Record<string, any>>,
|
||||
required: true,
|
||||
},
|
||||
formItems: {
|
||||
type: Array as PropType<FormItem[]>,
|
||||
default: () => [],
|
||||
},
|
||||
showButtons: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
searchButtonText: {
|
||||
type: String,
|
||||
default: '查询',
|
||||
},
|
||||
resetButtonText: {
|
||||
type: String,
|
||||
default: '重置',
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: Record<string, any>): void
|
||||
(e: 'search'): void
|
||||
(e: 'reset'): void
|
||||
}>()
|
||||
|
||||
// 使用本地响应式副本,避免直接修改 props
|
||||
const localModel = reactive<Record<string, any>>({})
|
||||
|
||||
// 初始化本地模型
|
||||
const initLocalModel = () => {
|
||||
Object.keys(localModel).forEach(key => delete localModel[key])
|
||||
Object.assign(localModel, props.modelValue)
|
||||
}
|
||||
|
||||
// 监听外部值变化
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
Object.keys(localModel).forEach(key => delete localModel[key])
|
||||
Object.assign(localModel, val)
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
|
||||
// 监听本地值变化,同步到外部
|
||||
watch(
|
||||
localModel,
|
||||
(val) => {
|
||||
emit('update:modelValue', { ...val })
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
const handleSearch = () => {
|
||||
emit('search')
|
||||
}
|
||||
|
||||
const handleReset = () => {
|
||||
emit('reset')
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'SearchForm',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
</style>
|
||||
Reference in New Issue
Block a user