Files
vue3/packages/select-table-modal/index.vue
2023-07-21 22:14:10 +08:00

206 lines
5.3 KiB
Vue

<!--
* @Author: zhaojinfeng 121016171@qq.com
* @Date: 2023-07-18 12:30:07
* @LastEditors: zhaojinfeng 121016171@qq.com
* @LastEditTime: 2023-07-21 22:13:32
* @FilePath: \vue3\packages\select-table-modal\index.vue
* @Description: 模态框选择表格
*
-->
<template>
<span v-if="!hideButton" @click="open">
<slot>
<el-button type="primary" plain>点击选择</el-button>
</slot>
</span>
<el-config-provider :locale="locale">
<el-dialog v-model="showDialog" :title="title" :width="width" append-to-body @open="getList" @closed="closed">
<el-form ref="queryRef" :modal="queryParams" inline>
<el-form-item v-for="formItem in formItems" :key="formItem.prop" :label="formItem.label" :prop="formItem.prop">
<el-select v-if="formItem.selectOptions" :placeholder="formItem.placeholder">
<el-option v-for="option in formItem.selectOptions" :key="option.value" :value="option.value">
{{ option.label }}
</el-option>
</el-select>
<el-input v-else v-model="queryParams[formItem.prop]" :placeholder="formItem.placeholder" />
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loading" @click="getList">
查询
</el-button>
<el-button :loading="loading" @click="resetQuery">
重置
</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
border
:data="tableData"
highlight-current-row
:row-key="rowKey"
:empty-text="emptyText"
@current-change="handleCurrentChange"
>
<el-table-column v-for="column in columns" :key="column.prop" :align="column.align || 'center'" :label="column.label" :prop="column.prop" :formatter="column.formatter" />
</el-table>
<div w-full h-70px relative>
<el-pagination
v-model:current-page="queryParams.pageNum"
v-model:page-size="queryParams.pageSize"
absolute
right-50px
top-20px
background
hide-on-single-page
:layout="layout"
:page-sizes="pageSizes"
:pager-count="pagerCount"
:total="total"
@size-change="handleSizeChange"
@current-change="getList"
/>
</div>
<template #footer>
<el-space>
<el-button type="primary" @click="confirm">
确定
</el-button>
<el-button @click="showDialog = false">
取消
</el-button>
</el-space>
</template>
</el-dialog>
</el-config-provider>
</template>
<script lang="ts" setup name="ThSelectTableModal">
import type { FormInstance, TableColumnCtx, TableInstance } from 'element-plus'
import locale from 'element-plus/lib/locale/lang/zh-cn'
const props = withDefaults(
defineProps<{
emptyText?: string
value?: any
rowKey?: string
show?: boolean
columns: Partial<TableColumnCtx<any>>[]
formItems: FormItem[]
defaultParams?: Record<string, any>
request: (args: any) => Promise<Page>
layout?: string
pageSizes?: number[]
pagerCount?: number
hideButton?: boolean
hidePagination?: boolean
title?: string
width?: string | number
}>(),
{
hidePagination: false,
layout: 'total, sizes, prev, pager, next, jumper',
rowKey: 'id',
pageSizes: () => [10, 20, 30, 50],
pagerCount: () => document.body.clientWidth < 992 ? 5 : 7,
hideButton: false,
width: '1000px',
title: '选择',
emptyText: '暂无数据',
},
)
const emit = defineEmits<{
(event: 'update:show', show: boolean): void
(event: 'update:value', show: any): void
(event: 'confirm', row: any): void
}>()
interface FormItem {
label: string
prop: string
placeholder?: string
selectOptions?: {
label: string
value: string
}[]
}
const showDialog = ref(false)
let tableData = $ref<any[]>([])
let selection = $ref<any>()
function confirm() {
emit('confirm', selection)
if (props.hideButton)
emit('update:show', false)
else
showDialog.value = false
}
function open() {
if (props.hideButton)
emit('update:show', true)
else
showDialog.value = true
}
let total = $ref(0)
function handleCurrentChange(val?: any) {
selection = val
}
/* 表单绑定的ref */
const queryRef = $ref<FormInstance>(null)
const tableRef = $ref<TableInstance>(null)
/* 初始加载 */
let loading = $ref(false)
/* 查询参数 */
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
})
/** 查询表格数据 */
async function getList() {
loading = true
tableData = []
try {
const response = await props.request({
...props.defaultParams,
...queryParams,
})
tableData = response.rows
const row = tableData.find(row => row[props.rowKey] === props.value)
total = response.total
if (row)
tableRef?.setCurrentRow(row)
}
finally {
loading = false
}
}
/** 重置按钮操作 */
function resetQuery() {
queryRef?.resetFields()
queryParams.pageNum = 1
getList()
}
function handleSizeChange(val: number) {
if (queryParams.pageNum * val > total)
queryParams.pageNum = 1
}
function closed() {
queryRef?.resetFields()
tableData = []
queryParams.pageNum = 1
selection = undefined
}
watch(() => props.show,
(show) => {
showDialog.value = show
})
</script>