Skip to content

Commit

Permalink
feat: add BaseTableSearch component
Browse files Browse the repository at this point in the history
  • Loading branch information
flingyp committed Jun 29, 2023
1 parent f048730 commit 7470c8c
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 74 deletions.
3 changes: 3 additions & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ declare module '@vue/runtime-core' {
export interface GlobalComponents {
BaseTable: typeof import('./src/components/common/BaseTable.vue')['default']
BaseTableHandle: typeof import('./src/components/common/BaseTableHandle.vue')['default']
BaseTableSearch: typeof import('./src/components/common/BaseTableSearch.vue')['default']
Echarts: typeof import('./src/components/common/Echarts.vue')['default']
'IconAntDesign:fullscreenExitOutlined': typeof import('~icons/ant-design/fullscreen-exit-outlined')['default']
'IconAntDesign:fullscreenOutlined': typeof import('~icons/ant-design/fullscreen-outlined')['default']
Expand Down Expand Up @@ -47,6 +48,7 @@ declare module '@vue/runtime-core' {
NColorPicker: typeof import('naive-ui')['NColorPicker']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDataTable: typeof import('naive-ui')['NDataTable']
NDatePicker: typeof import('naive-ui')['NDatePicker']
NDescriptions: typeof import('naive-ui')['NDescriptions']
NDescriptionsItem: typeof import('naive-ui')['NDescriptionsItem']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
Expand All @@ -66,6 +68,7 @@ declare module '@vue/runtime-core' {
NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NOption: typeof import('naive-ui')['NOption']
NSelect: typeof import('naive-ui')['NSelect']
NSpin: typeof import('naive-ui')['NSpin']
NSwitch: typeof import('naive-ui')['NSwitch']
Expand Down
40 changes: 4 additions & 36 deletions src/components/common/BaseTable.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,9 @@
<script setup lang="ts">
import { DataTableColumn, PaginationProps, VAdmireTableSize } from 'naive-ui'
import { RowData } from 'naive-ui/es/data-table/src/interface'
import BaseTableHandle from './BaseTableHandle.vue'
import { BaseTableProps } from '~/types'
defineOptions({ name: 'BaseTable' })
interface BaseTableProps {
headers: Array<DataTableColumn>
data: RowData[]
border?: boolean // 表格有无边框
singleColumn?: boolean // 表格有无行分割线
singleLine?: boolean // 表格有无列分割线
size?: VAdmireTableSize // 表格尺寸大小
striped?: boolean // 表格条纹渲染
maxHeight?: number // 表格最大高度
minHeight?: number // 表格最小高度
loading?: boolean // 表格加载状态
pagination?: PaginationProps // 表格分页
rowKey?: string // 表格行选中所绑定的Key
searchValue?: string // 搜索框关键词
scrollX?: number // 表格横向宽度
isEnableVirtualScroll?: boolean // 是否开启虚拟滚动
}
const props = withDefaults(defineProps<BaseTableProps>(), {
border: true,
singleColumn: false,
Expand All @@ -38,33 +19,20 @@ const props = withDefaults(defineProps<BaseTableProps>(), {
scrollX: undefined,
isEnableVirtualScroll: false,
})
defineEmits(['checkedRowKeys'])
const virtualScroll = computed(() => {
if (props.isEnableVirtualScroll && props.maxHeight) return true
return false
})
const emit = defineEmits(['checkedRowKeys', 'update:searchValue', 'addData', 'exportExcel', 'search'])
const selectedRowKeys = (row: RowData) => row.id
const tableSearchValue = ref(props.searchValue)
watch(tableSearchValue, (value) => emit('update:searchValue', value))
const baseTableHandleAddData = () => emit('addData')
const baseTableHandleExportFile = () => emit('exportExcel')
const baseTableHandleSearch = () => emit('search')
</script>

<template>
<div>
<div class="mb-4 flex items-center justify-end space-x-1">
<BaseTableHandle
v-model:value="tableSearchValue"
@add="baseTableHandleAddData"
@export="baseTableHandleExportFile"
@search="baseTableHandleSearch"
/>
</div>
<slot name="search" />
<slot name="handle" />
<NDataTable
:columns="headers"
:data="data"
Expand Down
31 changes: 4 additions & 27 deletions src/components/common/BaseTableHandle.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
<script setup lang="ts">
import RenderIconify from '~/components/common/RenderIconify.vue'
interface BaseTableHandleProps {
value: string
}
import { BaseTableHandleProps } from '~/types'
withDefaults(defineProps<BaseTableHandleProps>(), {
value: '',
})
defineEmits(['add', 'export', 'search', 'update:value'])
defineEmits(['add', 'export'])
</script>

<template>
<NInput
placeholder="搜索框"
autosize
size="small"
class="w-48"
:value="value"
@update:value="$emit('update:value', $event)"
>
<template #prefix>
<RenderIconify icon="uil:comment-alt-search" />
</template>
</NInput>
<NButton
type="primary"
size="small"
class="px-4"
@click="$emit('search')"
@click="$emit('add')"
>
搜索
新增
</NButton>
<NButton
type="info"
Expand All @@ -42,11 +26,4 @@ defineEmits(['add', 'export', 'search', 'update:value'])
>
导出
</NButton>
<NButton
size="small"
class="px-4"
@click="$emit('add')"
>
新增
</NButton>
</template>
58 changes: 58 additions & 0 deletions src/components/common/BaseTableSearch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<script setup lang="ts">
import { RecordSearchItem } from '~/types'
const props = defineProps({
searchFormList: {
type: Array<RecordSearchItem>,
default: () => [],
},
})
const emit = defineEmits(['update:searchFormList', 'search'])
const searchForm = ref(props.searchFormList)
watch(searchForm, (newValue) => {
emit('update:searchFormList', newValue)
}, { deep: true })
</script>

<template>
<NForm
label-placement="left"
label-width="auto"
>
<NFormItem
v-for="search in searchForm"
:key="search.key"
:label="search.label"
>
<NInput
v-if="search.type === 'input'"
v-model:value="search.value"
:placeholder="search.placeholder"
/>
<NSelect
v-else-if="search.type === 'select'"
v-model:value="search.value"
:placeholder="search.placeholder"
:options="search.options"
/>
<NDatePicker
v-else-if="search.type === 'date'"
v-model:formatted-value="search.value"
type="date"
class="w-full"
:placeholder="search.placeholder"
/>
</NFormItem>
<NFormItem>
<NButton
type="primary"
class="px-6"
@click="$emit('search')"
>
搜索
</NButton>
</NFormItem>
</NForm>
</template>
20 changes: 20 additions & 0 deletions src/types/components/BaseTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { DataTableColumn, PaginationProps, VAdmireTableSize } from 'naive-ui'
import { RowData } from 'naive-ui/es/data-table/src/interface'

export interface BaseTableProps {
headers: Array<DataTableColumn>
data: RowData[]
border?: boolean // 表格有无边框
singleColumn?: boolean // 表格有无行分割线
singleLine?: boolean // 表格有无列分割线
size?: VAdmireTableSize // 表格尺寸大小
striped?: boolean // 表格条纹渲染
maxHeight?: number // 表格最大高度
minHeight?: number // 表格最小高度
loading?: boolean // 表格加载状态
pagination?: PaginationProps // 表格分页
rowKey?: string // 表格行选中所绑定的Key
searchValue?: string // 搜索框关键词
scrollX?: number // 表格横向宽度
isEnableVirtualScroll?: boolean // 是否开启虚拟滚动
}
3 changes: 3 additions & 0 deletions src/types/components/BaseTableHandle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface BaseTableHandleProps {
value: string
}
11 changes: 11 additions & 0 deletions src/types/components/BaseTableSearch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { SelectMixedOption } from 'naive-ui/es/select/src/interface'

export interface RecordSearchItem {
label: string
key: string
type: 'input' | 'select' | 'date'
placeholder: string
value: any
options?: SelectMixedOption[]
[key: string]: any
}
4 changes: 3 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from '.'
export * from './components/BaseTable'
export * from './components/BaseTableHandle'
export * from './components/BaseTableSearch'
92 changes: 82 additions & 10 deletions src/views/features/Table.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<script setup lang="ts">
import { DataTableColumn, NButton } from 'naive-ui'
import BaseTable from '~/components/common/BaseTable.vue'
import BaseTableHandle from '~/components/common/BaseTableHandle.vue'
import BaseTableSearch from '~/components/common/BaseTableSearch.vue'
import { getBaseTableData } from '~/requests'
import { RecordSearchItem } from '~/types'
interface PersonInfo {
name: string
Expand Down Expand Up @@ -111,6 +114,8 @@ pagination.value.onUpdatePageSize = async (pageSize: number) => {
pagination.value.pageSize = pageSize
await getData()
}
// add table data
const addTableData = () => info('点击新增')
// export table data to excel file
const exportExcelFile = () => {
Expand All @@ -125,15 +130,66 @@ const exportExcelFile = () => {
exportExcel('Sheet1', '基础表格文件', ['名称', '出生日期', '家庭住址', '邮政编码', '性别'], sourceData)
}
// search table data
const searchData = () => info('搜索数据')
// add table data
const addTableData = () => info('点击新增')
// checked row keys
const checkedRowKeys = (id: string) => (success(`选中行所绑定的ID值:${id}`))
// config search from list
const searchFormList = ref<RecordSearchItem[]>([
{
label: '序号',
key: 'id',
type: 'input',
placeholder: '请输入序号',
value: '',
},
{
label: '名称',
key: 'name',
type: 'input',
placeholder: '请输入名称',
value: '',
},
{
label: '性别',
key: 'sex',
type: 'select',
placeholder: '请选择性别',
value: undefined,
options: [
{
label: '',
value: 1,
},
{
label: '',
value: 2,
},
],
},
{
label: '出生日期',
key: 'birthday',
type: 'date',
placeholder: '请输入出生日期',
value: undefined,
},
{
label: '家庭住址',
key: 'address',
type: 'input',
placeholder: '请输入家庭住址',
value: '',
},
{
label: '邮政编码',
key: 'postalCode',
type: 'input',
placeholder: '请输入邮政编码',
value: '',
},
])
const clickSearch = () => (info('点击搜索'))
onMounted(async () => {
const { total } = await getData()
pagination.value.pageCount = total
Expand All @@ -143,16 +199,32 @@ onMounted(async () => {
<template>
<div>
<BaseTable
v-model:search-value="searchValue"
size="small"
:loading="isLoading"
:headers="baseTableColumns"
:data="tableData || []"
:pagination="pagination"
@search="searchData"
@checked-row-keys="checkedRowKeys"
@add-data="addTableData"
@export-excel="exportExcelFile"
/>
>
<template #search>
<div class="border border-vBorderLight dark:border-vBorderDark rounded p-4 mb-2">
<BaseTableSearch
v-model:search-form-list="searchFormList"
class="grid grid-cols-4 gap-x-4"
@search="clickSearch"
/>
</div>
</template>
<template #handle>
<div class="mb-2 flex items-center justify-end space-x-1">
<BaseTableHandle
v-model:value="searchValue"
@add="addTableData"
@export="exportExcelFile"
/>
</div>
</template>
</BaseTable>
</div>
</template>

0 comments on commit 7470c8c

Please sign in to comment.