赞
踩
上文是对el-table的基本封装上增加slot插槽,并且对col插槽进行拓展,本文主要时增加分页组件,同时进行slot传递
//BaseTable.vue没有变
<template> <el-table> <template v-for="name in tableSlots" :key="name" #[name]> <slot :name="name"></slot> </template> <el-table-column v-for="(col, index) in attrs.config" :key="index" v-bind="col" > <template v-if="col.slot" #[getColSlot(col)]="scope"> <slot :name="col.slot" v-bind="scope"></slot> </template> </el-table-column> </el-table> </template> <script lang="ts" setup> const attrs = useAttrs(); const slots = useSlots(); const tableSlots = computed(() => { // 原生el-table插槽只有default,append,empty // 原生el-table-column插槽只有table插槽只有default,header // 这里将header单独处理,认为是col的插槽,从table插槽中排除 return Object.keys(slots).filter((name) => name !== "header"); }); const getColSlot = (col) => { return col.slot === "header" ? "header" : "default"; }; </script>
//CustomTable.vue增加空表格插槽,分页组件,slot传递,必要时可以扩展多个CustomTable组件
<template> <BaseTable v-bind="tableAttrs" > <template #empty> empty </template> <!--slots传递 --> <template v-for="name in Object.keys(slots)" :key="name" #[name]="scope" > <slot :name="name" v-bind="scope"></slot> </template> </BaseTable> <el-pagination class="page" v-if="attrs.page" v-bind="page" /> </template> <script lang="ts" setup> import BaseTable from "./BaseTable.vue"; const attrs = useAttrs(); const slots = useSlots(); const tableAttrs = computed(() => { const ret = {}; Object.keys(attrs) .filter((attr) => attr !== "page") .map((attr) => (ret[attr] = attrs[attr])); return ret; }); // 提供分页默认值 const page = computed(() => { return attrs.page ? { ...attrs.page, // "current-page": 1, //如果传入了 current-page,必须监听 current-page 变更的事件(@update:current-page) // "page-size":20, //如果传入了 page-size,且布局包含 page-size 选择器(即 layout 包含 sizes),必须监听 page-size 变更的事件(@update:page-size),否则分页大小的变化将不起作用。 "page-sizes": attrs.page.pageSizes??[10, 20, 30, 40], layout:attrs.page.layout??"total, sizes, prev, pager, next, jumper", total: attrs.page.total??0, } : null; }); </script> <style> .page{ display: flex; justify-content: center; } </style>
// index.vue
<template> <CustomTable :config="config" :data="tableData" :style="{ width: '800px' }" :page="true" > <template #status="scope"> <el-text :type="scope.row.status.type">{{ scope.row.status.content }}</el-text> </template> <template #btn="scope"> <el-button type="primary">{{ scope.row.btn }}</el-button> </template> <!-- 如有多个类似slot,也可以用如下方式渲染 --> <!-- <template v-for="(col,index) in config.filter(item=>item.slot && item.slot!=='header')" :key="index" #[col.slot]="scope"> <el-button type="primary">{{ scope.row.btn }}</el-button> </template> --> <template #header="scope"> <el-button type="primary">{{ scope.column.label }}</el-button> </template> </CustomTable> </template> <script lang="ts" setup> import CustomTable from "./CustomTable.vue"; const config = ref([ { type: "selection", }, { prop: "date", label: "日期", width: "180", }, { prop: "name", label: "姓名", }, { prop: "status", label: "状态", slot: "status", width: "180", }, { prop: "btn", label: "操作", slot: "btn", width: "180", }, { prop: "header", label: "按钮header", slot: "header", width: "180", }, ]); const tableData = [ { date: "2016-05-03", name: "张三", status: { content: "工作", type: "success" }, btn: "confirm", }, { date: "2016-05-02", name: "李四", status: { content: "出差", type: "primary" }, btn: "confirm", }, { date: "2016-05-04", name: "王五", status: { content: "休假", type: "danger" }, btn: "confirm", }, ]; </script>
如果分页组件使用默认值,绑定true即可,如果需要自定义,绑定对象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。