当前位置:   article > 正文

vue3 element plus el-table封装(三)

element plus el-table封装

上文是对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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

//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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

// 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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

如果分页组件使用默认值,绑定true即可,如果需要自定义,绑定对象
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/684274
推荐阅读
相关标签
  

闽ICP备14008679号