Element-plus 封装分页组件和表格组件,实现跨页全选

在这里插入图片描述

<template>
  <!-- 是否显示表头的全选 -->
  <div :class="{isSingle:props.isSingle}">
    <el-table
        :header-cell-style="props.headerCellStyle"
        :header-row-style="props.headerRowStyle"
        :data="props.tableData"
        :max-height="props.maxHeight"
        :size="props.size"
        ref="tableRef"
        style="width: 100%"
        :highlight-current-row="props.highlightCurrentRow"
        @current-change="changeCurrent"
        @selection-change="changeSelect"
        @select="changeSelectTap"
        @select-all="changeSelectAll"
        :row-key="props.rowKey"
        :tree-props="props.treeProps||treeProps"
    >
    <!-- 是否开启多选功能 -->
      <el-table-column v-if="props.isSelect" :reserve-selection="true" type="selection" width="50"/>
      <!-- 遍历表头数据 -->
      <template v-for="(item, index) in props.header">
        <el-table-column
            :key="index"
            :align="item.align || 'center'"
            :sortable="item.sortable"
            :width="item.width"
            :min-width="item.minWidth"
            :label="item.label"
            :prop="item.prop"
            :fixed="item.fixed"
            v-if="item.isShow == false ? false : true"
            show-overflow-tooltip
        >
        <!-- 自定义行slot -->
          <template v-if="item.isCustom" #default="scope">
            <slot :name="item.prop" :row="scope.row" :column="scope.column" :index="scope.$index"></slot>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <!-- 分页,传了分页数据就会展示 -->
    <div v-if="page" class="mt15 flex-center">
      <el-pagination
          :currentPage="props.page?.pageIndex"
          :page-size="props.page?.pageSize"
          :page-sizes="[10, 20, 30]"
          layout="sizes, prev, pager, next, jumper"
          :total="props.page?.total"
          :background="true"
          :hide-on-single-page="false"
          @size-change="changeSize"
          @current-change="changePage"
      >
      </el-pagination>
    </div>
  </div>
</template><script lang="ts" setup>import {ref} from "vue";
import { ElTable,ElPagination } from "element-plus";//表格实例
const tableRef=ref();//表格数据的配置项
interface Header {
  label: string;
  prop?: string;
  width?: string | number;
  minWidth?: string | number;
  sortable?: boolean;
  align?: string;
  isCustom?: boolean;
  fixed?: string;
  isShow?: boolean;
}
//分页数据配置项
interface Page {
  total?: number; 
  pageSize?: number;
  pageIndex?: number;
  background?: boolean;
}
//props配置项
interface Props {
  tableData: Array<any>; //表格数据
  page?: Page; //分页数据
  isSelect?: boolean; //是否支持多选
  isSingle?: boolean; //是否隐藏全选
  size?: 'large' | 'default' | 'small'; //table的尺寸
  header: Array<Header>; //表头数据
  maxHeight?: string | number;
  headerRowStyle?: Function | object;
  headerCellStyle?: Function | object;
  highlightCurrentRow?: boolean;
  rowKey?: string,
  treeProps?: Function |object
}const treeProps={ children: 'children', hasChildren: 'hasChildren' }//设置props默认配置项
const props = withDefaults(defineProps<Props>(), {
  isSelect: false,
  isOperation: true,
  size: 'default',
  highlightCurrentRow: false,
  rowKey: 'id',
  isSingle:false
});
​
​
// 每页条数 改变时触发
const changeSize = (size: number) => {
  emit('changeSize', size);
}//翻页时触发
const changePage = (page: number) => {
  emit('changePage', page);
}// 选择行
const changeCurrent = (currentRow: any, oldCurrentRow: any) => {
  emit('changeCurrent', {currentRow, oldCurrentRow})
}
// 不管全选还是勾选都会触发
const changeSelect = (val: any) => {
  emit('onSelect', val)
}
// 手动全选
const changeSelectAll = (val: any) => {
  emit('onSelectAll', val)
}
// 手动勾选
const changeSelectTap = (val: any,row:any) => {
  emit('onSelectTap', val,row)
}
//让父组件可以获取到table实例
defineExpose({ tableRef})
//注册事件
const emit = defineEmits(['changeSize', 'changePage', 'changeCurrent', 'onSelect','onSelectTap','onSelectAll']);
</script><style lang="scss" scoped>
.isSingle{
  :deep(*){
    .el-table__header{
      .el-checkbox{
        visibility: hidden;
      }
    }
  }
}
</style>

在这里插入图片描述

<template>
  <MyTable
    ref="tableRef"
    :page="tableData.page"
    :isSelect="true"
    :rowKey="'id'"
    @changeSize="(size) => changeSize(size)"
    @changePage="(page) => changePage(page)"
    :header="header"
    :tableData="
      tableData.data.slice(
        (tableData.page.pageIndex - 1) * tableData.page.pageSize,
        tableData.page.pageIndex * tableData.page.pageSize
      )
    "
    @onSelectTap="changeSelectTap"
    @onSelectAll="changeSelectAll"
  >
    <template v-slot:sex="scope">
      {{ scope.row.sex == "0" ? "男" : "女" }}
    </template>
    <template v-slot:operation="scope">
      <el-button @click="handelEdit(scope.row)">编辑</el-button>
      <el-button @click="handelDel(scope.row)">删除</el-button>
    </template>
  </MyTable>
</template><script lang="ts" setup>
import MyTable from "./components/myTable.vue";
import { ref, reactive, onMounted } from "vue";
const tableRef = ref();
// 表头
const header = reactive([
  {
    label: "姓名",
    prop: "name",
  },
  {
    label: "性别",
    prop: "sex",
    isCustom: true,
  },
  {
    label: "年龄",
    prop: "age",
  },
  {
    label: "操作",
    prop: "operation",
    isCustom: true,
    fixed: "right",
    align: "center",
    width: 200,
  },
]);
// 表格数据
const tableData = reactive({
  data: [],
  searchForm: {},
  page: {
    pageIndex: 1,
    pageSize: 10,
    total: 500,
  },
});
const handelEdit = (val) => {
  console.log("编辑");
};
const handelDel = (val) => {
  console.log("删除");
};
onMounted(() => {
  //模拟请求数据
  setTimeout(() => {
      //随机生成一些表格数据
    for (let i = 0; i < 500; i++) {
      let obj = {
        id:i,
        name: `c${i + 1}`,
        sex: parseInt(String(Math.random() * 2)),
        age: Math.round(Math.random() * 100),
      };
      tableData.data.push(obj);
    }
  }, 1500);
});
</script><style scoped></style>

在这里插入图片描述

//已被勾选的数据id
const ids = ref('');
//多选
const changeSelectTap = (val: any) => {  
    ids.value = val.map((v: any) => v.id).join(',');
};
//是否全选
const isSelectAll = ref(false);
const changeSelectAll = (val: any) => {
    if (!isSelectAll.value) {
        isSelectAll.value = true;
        ids.value = tableData.data.map((v: any) => v.id).join(',');
        console.log(ids.value);
    } else {
        ids.value = '';
        isSelectAll.value = false;
        console.log(ids.value);
    }
};
//修改每页的数据数量
const changeSize = (size: any) => {
  tableData.page.pageIndex = 1;
  tableData.page.pageSize = size;let selectData = ids.value.split(",");
​
  tableData.data.forEach((v: any) => {
    let index = selectData.findIndex((t) => {
      return v.id == t;
    });
    tableRef.value.tableRef.toggleRowSelection(v, index != -1);
  });
};//修改当前页
const changePage = (page: any) => {
  tableData.page.pageIndex = page;
  let selectData = ids.value.split(",");
  tableData.data.forEach((v: any) => {
    let index = selectData.findIndex((t) => {
      return v.id === t;
    });
    tableRef.value.tableRef.toggleRowSelection(v, index != -1);
  });
};

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackieChan_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值