vue3.2封装一个listTable组件
ListTable.vue
<!-- table组件 -->
<template>
<div class="table-wrap">
<el-table
ref="listTable"
:class="`list-table`"
:data="tableData"
:header-cell-class-name="`list-table-header`"
style="width: 100%"
border
stripe
height="100%"
:header-row-class-name="headerColor"
:row-class-name="tableRewClassName"
@selection-change="handleSelectionChange"
>
<el-table-column
v-if="isSelect"
type="selection"
align="center"
width="50"
/>
<el-table-column
v-if="isSerial"
type="index"
:label="'序号'"
width="60"
/>
<el-table-column
v-for="(item, index) in tableCol"
:key="index"
:prop="item.prop"
:label="item.label"
:width="item.width"
:align="item.align"
>
<!-- 判断要渲染的组件 -->
<template
v-if="item.formatter && typeof item.formatter !== 'function'"
v-slot:default="{ row, column, $index }"
>
<component
:is="item.formatter"
:key="row.id"
:table-data="tableData"
:row="row"
:column="column"
:index="$index"
:col="item"
:cell-value="row[item.prop]"
:status="item.status"
/>
</template>
<template v-else-if="item.link" v-slot:default="{ row, column }">
<span class="jump-color" @click="handleOperate(row, column)">{
{
row[item.prop]
}}</span>
</template>
<template v-else v-slot="scope">
{
{
scope.row[item.prop] }}
</template>
</el-table-column>
<!-- 多级表头插槽 示例:<template v-slot:multistageHeader></template> -->
<slot name="multistageHeader" />
<el-table-column v-if="isOperation" :label="operationText">
<template #default="scope">
<slot name="operation" :scope="scope"></slot>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup lang="ts" name="ListTable">
import {
ref } from 'vue'
type Props = {
tableData?: Array<any>
tableCol?: Array<any>
isLoading?: boolean
isSerial?: boolean
showSummary?: boolean
summaryMethod?: Function
spanMethod?: Function
cellClassName?: Function
isOperation?: boolean
operationText?: string
isSelect?: boolean
selectData?: Array<any>
isRowClick?: boolean
row?: object
btnConfig?: object
}
const listTable = ref<HTMLTableElement>()
const props = withDefaults(defineProps<Props>(), {
operationText: '操作',
isRowClick: false
})
const toRefs = <T extends object>(object: T) => {
const obj: any = {
}
for (let key in object) {
obj[key] = toRef(object, key)
}
return obj
}
const {
isRowClick } = toRefs(props)
const emit = defineEmits(['row-click', 'tableMultipleSelection'])
const rowIndex = ref<string>('')
const headerColor = ({
rowIndex }) => {
if (rowIndex > 0) return 'header-color'
}
const tableRewClassName = ({
row, rowIndex }) => {
if (!isRowClick) return
row.index = rowIndex
if (rowIndex.value === rowIndex) return 'row-style'
}
const handleSelectionChange = (row: any) => {
emit('tableMultipleSelection', row)
}
</script>
<style lang="scss" scoped>
.table-wrap {
width: 100%;
height: 100%;
.list-table {
height: calc(100% - 50px);