feat
This commit is contained in:
217
src/components/search-table/index.vue
Normal file
217
src/components/search-table/index.vue
Normal file
@@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<div class="search-table-container">
|
||||
<a-card class="general-card" :title="title">
|
||||
<!-- 搜索表单 -->
|
||||
<SearchForm
|
||||
:model-value="formModel"
|
||||
:form-items="formItems"
|
||||
:show-buttons="showSearchButtons"
|
||||
:search-button-text="searchButtonText"
|
||||
:reset-button-text="resetButtonText"
|
||||
@update:model-value="handleFormModelUpdate"
|
||||
@search="handleSearch"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
|
||||
<a-divider style="margin-top: 0" />
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<DataTable
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
:bordered="bordered"
|
||||
:show-toolbar="showToolbar"
|
||||
:show-download="showDownload"
|
||||
:show-refresh="showRefresh"
|
||||
:show-density="showDensity"
|
||||
:show-column-setting="showColumnSetting"
|
||||
:download-button-text="downloadButtonText"
|
||||
:refresh-tooltip-text="refreshTooltipText"
|
||||
:density-tooltip-text="densityTooltipText"
|
||||
:column-setting-tooltip-text="columnSettingTooltipText"
|
||||
@page-change="handlePageChange"
|
||||
@refresh="handleRefresh"
|
||||
@download="handleDownload"
|
||||
@density-change="handleDensityChange"
|
||||
@column-change="handleColumnChange"
|
||||
>
|
||||
<template #toolbar-left>
|
||||
<slot name="toolbar-left" />
|
||||
</template>
|
||||
<template #toolbar-right>
|
||||
<slot name="toolbar-right" />
|
||||
</template>
|
||||
<!-- 动态插槽透传 -->
|
||||
<template v-for="col in slotColumns" :key="col.dataIndex" #[String(col.slotName)]="slotProps">
|
||||
<slot :name="col.slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</DataTable>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, PropType } from 'vue'
|
||||
import SearchForm from '../search-form/index.vue'
|
||||
import type { FormItem } from '../search-form/types'
|
||||
import DataTable from '../data-table/index.vue'
|
||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
|
||||
|
||||
type SizeProps = 'mini' | 'small' | 'medium' | 'large'
|
||||
|
||||
const props = defineProps({
|
||||
// 表单相关
|
||||
formModel: {
|
||||
type: Object as PropType<Record<string, any>>,
|
||||
required: true,
|
||||
},
|
||||
formItems: {
|
||||
type: Array as PropType<FormItem[]>,
|
||||
default: () => [],
|
||||
},
|
||||
showSearchButtons: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
searchButtonText: {
|
||||
type: String,
|
||||
default: '查询',
|
||||
},
|
||||
resetButtonText: {
|
||||
type: String,
|
||||
default: '重置',
|
||||
},
|
||||
// 表格相关
|
||||
data: {
|
||||
type: Array as PropType<any[]>,
|
||||
default: () => [],
|
||||
},
|
||||
columns: {
|
||||
type: Array as PropType<TableColumnData[]>,
|
||||
required: true,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
pagination: {
|
||||
type: Object as PropType<{
|
||||
current: number
|
||||
pageSize: number
|
||||
total?: number
|
||||
}>,
|
||||
default: () => ({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
}),
|
||||
},
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 工具栏相关
|
||||
showToolbar: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showDownload: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showRefresh: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showDensity: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showColumnSetting: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 文本配置
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
downloadButtonText: {
|
||||
type: String,
|
||||
default: '下载',
|
||||
},
|
||||
refreshTooltipText: {
|
||||
type: String,
|
||||
default: '刷新',
|
||||
},
|
||||
densityTooltipText: {
|
||||
type: String,
|
||||
default: '密度',
|
||||
},
|
||||
columnSettingTooltipText: {
|
||||
type: String,
|
||||
default: '列设置',
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:formModel', value: Record<string, any>): void
|
||||
(e: 'search'): void
|
||||
(e: 'reset'): void
|
||||
(e: 'page-change', current: number): void
|
||||
(e: 'refresh'): void
|
||||
(e: 'download'): void
|
||||
(e: 'density-change', size: SizeProps): void
|
||||
(e: 'column-change', columns: TableColumnData[]): void
|
||||
}>()
|
||||
|
||||
// 计算需要插槽的列(动态插槽透传)
|
||||
const slotColumns = computed(() => {
|
||||
return props.columns.filter(col => col.slotName)
|
||||
})
|
||||
|
||||
const handleFormModelUpdate = (value: Record<string, any>) => {
|
||||
emit('update:formModel', value)
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
emit('search')
|
||||
}
|
||||
|
||||
const handleReset = () => {
|
||||
emit('reset')
|
||||
}
|
||||
|
||||
const handlePageChange = (current: number) => {
|
||||
emit('page-change', current)
|
||||
}
|
||||
|
||||
const handleRefresh = () => {
|
||||
emit('refresh')
|
||||
}
|
||||
|
||||
const handleDownload = () => {
|
||||
emit('download')
|
||||
}
|
||||
|
||||
const handleDensityChange = (size: SizeProps) => {
|
||||
emit('density-change', size)
|
||||
}
|
||||
|
||||
const handleColumnChange = (columns: TableColumnData[]) => {
|
||||
emit('column-change', columns)
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'SearchTable',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.search-table-container {
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user