用vue3和antd3二次封装table和分页器组件

项目场景:

如题:

我是一只刚入行不久的程序员新人,因为公司新项目要用vue3和antd3,而且要我封装一个公共的table组件,也是查了很多资料,看了很多大佬的代码,配合自己的修改写出来了,因为刚写出来,可能会有一些冗余代码,大家用的时候可以结合自己做一些修改。
因为是新人写的有点乱…见谅


直接上代码

子组件代码

<template>
  <div class="tablePaganations">
    <!-- 表格 -->
    <a-table
      :data-source="tableData"
      :pagination="false"
      :columns="columns"
      :row-selection="props.isSelect ? rowSelection1 : null" //是否多选
    >
      <template v-slot:[item]="scope" v-for="item in renderArr">
        <slot :name="item" :scope="scope"></slot>
      </template>
    </a-table>
    <!-- 分页器 -->
    <div class="paginationSetting">
      <div class="paginationSettingtext">
        <span>{{ total }} 条记录 </span>
        <span style="margin-left: 20px">{{ pageCurrent }} /
          {{ total == 0 ? 1 : Math.ceil(total / pageSize) }}</span>
      </div>
      <div class="paginations">
        <a-pagination
          :current="pageCurrent"
          :page-size-options="['5', '10', '20', '30', '40']"
          :total="total"
          show-size-changer
          show-quick-jumper
          :page-size="pageSize"
          @change="pageChange"
        >
          <template slot="buildOptionText" slot-scope="props">
            <span>{{ props.value }}/</span>
          </template>
        </a-pagination>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, useSlots,watch } from "vue";
const props = defineProps({
  Table: Object,
  column: Object,
  isSelect: Boolean,
});
let tableData = ref([]);
let total = ref(0); //多少条数据
const columns = ref([]);
let pageCurrent = ref(1); //当前第几页
let pageSize = ref(10); //每页多少行
if (props.Table.data) { //非空
  tableData.value = props.Table.data; //表单数据
}
if (props.Table.total) { //非空
  total.value = props.Table.total; //表单长度
}
if (props.column) { //非空
  //表单columns
  columns.value = props.column;
}
const slots = useSlots();
const renderArr = Object.keys(slots);
// console.log(renderArr);

const emit = defineEmits(['batch','changePage']) //子传父

const pageChange = (current, pagesize) => {
  //分页器改变事件
  // console.log("current", current, "pageSize", pagesize);
  pageCurrent.value = current;
  if(pageSize.value != pagesize){ //如果每页行数改变,页码改为1
    pageCurrent.value=1
  }
  pageSize.value = pagesize;
  emit('changePage',{pageCurrent:pageCurrent.value,pageSize:pageSize.value})
};
// watch(()=>pageSize.value,(newValue,oldValue)=>{ //监听pageSize的数据改变页码
//   // console.log('当前值',pageSize.value);
//   // console.log('新值',newValue);
//   // console.log('旧值',oldValue);
//   if(pageSize.value==newValue){
//     pageCurrent.value = 1
//     emit('showSize',{pageCurrent:pageCurrent.value,pageSize:pageSize.value})
//   }
// })
// 是否多选
const rowSelection1 = {
  onChange: (selectedRowKeys, selectedRows) => {
    // console.log(selectedRowKeys, selectedRows);
    emit("batch", selectedRowKeys);
  },
  getCheckboxProps: (record) => ({
    disabled: record.name === "Disabled User", // Column configuration not to be checked
    name: record.name,
  }),
};
</script>

<style scoped>
.tablePaganations {
  width: 100%;
  margin-top: 20px;
}
.paginationSetting {
  display: flex;
  justify-content: space-between;
  height: 35px;
  margin-top: 20px;
}
.paginationSettingtext {
  margin-left: 20px;
}
.paginationSettingtext span {
  color: gray;
  line-height: 35px;
}
.paginations {
  margin-right: 20px;
}
</style>

父组件代码,传的值和column我就不放在上面

<script setup>
const changePage = (val) =>{ //分页器改变返回值
  console.log('changePage',val);
}
const batch =(val)=>{ //多选改变返回值
  console.log('batch',val);
}
</script>
<template>
<div class="vue3_content">
            <!-- 二次封装的table组件 -->
            <tablePaganations
              :Table="tableValues"
              :column="columns"
              :isSelect="isSelect" //是否打开多选框
              @changePage="changePage"
              @batch="batch"
            >
            //这里是插槽,用于对表格进行操作,比如数据渲染和操作列的增删改查
              <template v-slot:bodyCell="{ scope }">
                <span v-if="scope.column.key!='action'">{{ setSlot(scope.column.key, scope.value) }}</span>
                //这里的action是操作列,判断是否为操作列对其进行修改
                <span v-else>
                  <a-button type="primary">编辑</a-button>
                  <a-divider type="vertical" />
                  <a-button>删除</a-button>
                </span>
              </template>
            </tablePaganations>
            <!-- --------------- -->
          </div>
</template>

最终效果:

完整版
最终效果
不加插槽的效果:
不加插槽的效果
感谢

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
实现跨页多选需要记录选中的数据的ID,可以使用Vue的Reactive响应式对象来进行数据绑定和监听。具体实现步骤如下: 1. 定义一个空数组selected,用来存储选中的数据的ID。 ```javascript import { reactive } from 'vue'; const state = reactive({ selected: [] }); ``` 2. 在表格的每一行中添加一个多选框,绑定一个change事件,根据选中状态添加或删除选中的数据的ID。 ```html <template> <a-table :dataSource="data" :columns="columns"> <template #selection="{row}"> <a-checkbox v-model:checked="isSelected(row.id)" @change="handleSelect(row.id, $event.target.checked)"></a-checkbox> </template> </a-table> </template> ``` ```javascript const handleSelect = (id, checked) => { if (checked) { state.selected.push(id); } else { state.selected.splice(state.selected.indexOf(id), 1); } }; ``` 3. 在表格的分页组件中添加一个自定义的选中项数量显示组件,根据selected数组的长度来显示选中项的数量。 ```html <template> <div> <a-pagination :total="total" :current="current" @change="handleChange"></a-pagination> <span>已选中 {{ selected.length }} 项</span> </div> </template> ``` 4. 在分页组件的change事件中,重新加载当前页的数据时,需要将之前选中的数据的ID与当前页的数据进行比对,保留选中状态。 ```javascript const handleChange = (page, pageSize) => { // 获取当前页的数据 const newData = fetchData(page, pageSize); // 比对选中状态 const selectedIds = new Set(state.selected); newData.forEach(item => { if (selectedIds.has(item.id)) { item.selected = true; } }); // 更新表格数据 state.data = newData; }; ``` 这样就可以实现跨页多选了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值