接触新项目的时候,经常会看到之前的同事二次封装了table表格,代码贴出来
<template>
<el-table :data="data" border v-loading="loading">
<el-table-column v-for="col in filterColumns" :key="col.label" v-bind="col">
<template v-if="col.slot" #="{ row }">
<slot :name="col.slot" :row="row"></slot>
</template>
// 实现自定义需求
<template v-else #="{ row }">
{{ row[col.prop] || "-" }}
</template>
<template v-if="col.label === '操作'" #header>
<el-popover
placement="bottom"
:width="80"
trigger="click"
:visible="visible"
>
<template #reference>
<div class="title" @click="visible = true">
<span>操作</span>
<el-icon><ArrowDown /></el-icon>
</div>
</template>
<el-checkbox-group v-model="tempCheckedLabels">
<el-checkbox
:label="item.label"
v-for="item in cbColumns"
:key="item.label"
/>
</el-checkbox-group>
<div>
<el-button size="small" @click="cancel">取消</el-button>
<el-button size="small" type="primary" @click="confirm"
>确定</el-button
>
</div>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-pagination
class="mt-20"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
:page-sizes="[10, 20, 30, 40]"
layout="prev, pager, next, jumper, ->, sizes, total"
@current-change="getList"
@size-change="getList"
>
</el-pagination>
</template>
<script lang="ts">
export default {
name: "XTable",
};
</script>
<script lang="ts" setup>
import { onMounted, ref, computed } from "vue";
import { ArrowDown } from "@element-plus/icons-vue";
const props = withDefaults(
defineProps<{
columns: any[];
getData: (page: number, limit: number) => {};
pagination: boolean;
}>(),
{
pagination: true,
}
);
const data = ref<any[]>([]);
const loading = ref(false);
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);
const getList = async () => {
loading.value = true;
const result: any = await props.getData(currentPage.value, pageSize.value);
data.value = result.records;
total.value = result.total;
loading.value = false;
};
onMounted(() => {
getList();
});
const visible = ref(false);
const checkedLabels = ref(props.columns.map((col) => col.label)); // 确定时才改变
const tempCheckedLabels = ref(checkedLabels.value); // 选择时会自动改变 取消时恢复为checkedLabels
const filterColumns = computed(() => {
// 要显示的列
return props.columns.filter((col) => checkedLabels.value.includes(col.label));
});
const cbColumns = computed(() => {
// 要显示的所有checkbox对应的列
return props.columns.filter((col) => col.label !== "操作");
});
// 取消
const cancel = () => {
visible.value = false;
tempCheckedLabels.value = checkedLabels.value;
};
// 确定
const confirm = () => {
visible.value = false;
checkedLabels.value = tempCheckedLabels.value;
};
</script>
<style scoped>
.title {
width: 80px;
display: flex;
align-items: center;
}
</style>