当前位置: 首页 > news >正文

vue3组件封装系列-表格及分页-第二弹

第二弹来了,不知道有多少人是看过我的第一篇文章的,今天本来是没想更新的,但是现在项目正在验收期准备上线,闲着还不如来发发文。虽然这两天可能会高产,下一次高产就不知道是什么时候了。话不多说,先上图。

在这里插入图片描述

上面就是效果图了,基于vue3+element-plus觉得还行的可以继续看下去

源码

src\components\MTable\index.vue

<template><div class="table-list-root"><el-tableref="mtable"v-loading="loading"v-bind="$attrs":border="border":header-row-style="defaultHeaderRowStyle":header-cell-style="defaultHeaderCellStyle":cell-style="defaultCellStyle"class="table-list__main"><template #empty><el-empty description="暂无数据" /></template><el-table-column v-for="filed in columns" :key="filed.prop" v-bind="filed"><template #header="{ $index}"><slot :name="`header-${filed.prop}`" :column="filed" :index="$index">{{filed.label}}</slot></template><template v-if="filed.prop && $slots[filed.prop]" #default="scope"><slot :name="filed.prop" :row="scope.row" /></template></el-table-column></el-table><div v-if="pagination" class="table-list__footer"><el-paginationv-bind="paginationProps"@current-change="handleCurrentChange"@size-change="handleSizeChange"/></div></div>
</template>
<script setup lang="ts">
import { type PropType, ref, toRefs } from 'vue';
import useTable from './uses/useTable';
import usePagination from './uses/usePagination';
defineOptions({inheritAttrs: false
});
type filed = {prop?: string;[propName: string]: any;
};
const props = defineProps({loading: {type: Boolean,default: false},// 表格列columns: {type: Array as PropType<filed[]>,default: () => []},border: {type: Boolean,default: true},pagination: {type: Object,default: () => null}
});
// 这里其实可以使用defineModel,我这样写只是为了让习惯vue2的稍微清晰一点
const emit = defineEmits(['update:pagination']);
const mtable = ref(null);
const { pagination } = toRefs(props);const { defaultHeaderRowStyle, defaultHeaderCellStyle, defaultCellStyle } = useTable();
const { paginationProps, handleSizeChange, handleCurrentChange } = usePagination(emit, pagination);
</script>

src\components\MTable\uses\useTable.ts

这个文件其实就是一些自定义样式,不想分开写的也可以写在一起

import { ref } from 'vue';export default function useTable() {const defaultHeaderRowStyle = ref({borderRadius: '4px 4px 0px 0px',backgroundColor: '#F8F8F8',padding: '0',height: '54px',lineHeight: '54px',});const defaultHeaderCellStyle = ref({backgroundColor: '#F8F8F8',color: '#282828',fontSize: '14px',padding: '0',height: '54px',});const defaultCellStyle = ref({color: '#323233',fontSize: '14px',lineHeight: '20px',});return {defaultHeaderRowStyle,defaultHeaderCellStyle,defaultCellStyle,};
}

src\components\MTable\uses\usePagination.ts

这里是关于分页的处理

import { computed } from 'vue';export default function usePagination(emit:any, pagination:any) {const paginationProps = computed(() => {const paginationVal = pagination.valuereturn {background: true,layout: 'prev, pager, next, sizes, jumper',currentPage: paginationVal.page,pageSize: paginationVal.size,...paginationVal,}});const handleSizeChange = (pageSize:number | string) => {emit('update:pagination', {...pagination.value,size: pageSize,});};const handleCurrentChange = (currentPage:number | string) => {emit('update:pagination', {...pagination.value,page: currentPage,});};return {paginationProps,handleSizeChange,handleCurrentChange,};
}

关于组件的源码其实就这些了,下面简单写个使用示例

<template>
<MTablev-model:pagination="pagination":loading="loading.tableLoading":data="tableData":columns="TABLECOLUMN"@update:pagination="getTableData"
><template #header-sent_staff="{column, index}">自定义成员列表头</template><template #sent_staff="{ row }">自定义成员列xxxxxx</template><template #action="{ row }"><el-button type="primary" link>预览</el-button><el-button type="primary" link>删除</el-button><el-button type="primary" link>再次发送</el-button></template>
</YzTable>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import MTable from '@/components/MTable/index.vue';
const searchQuery = ref({});
const pagination = ref({page: 1,size: 10,total: 0
});
const tableData = ref([]);
const loading = ref({tableLoading: false,
});onMounted(() => {handleQuery();
});// 点击查询
const handleQuery = async () => {pagination.value.page = 1;await getTableData();
};// 请求表格数据
const getTableData = async () => {const dataValue = {...searchQuery.value,page: pagination.value.page,page_size: pagination.value.size};loading.value.tableLoading = true;try {const data = await xxxxxxxx(dataValue);tableData.value = data.data;pagination.value.total = data.total;} finally {loading.value.tableLoading = false;}
};const TABLECOLUMN = [{label: '序号',type: 'index',width: 70},{label: '计划名称',prop: 'name'},{label: '发送类型',prop: 'send_type',formatter: (row: any) => planSendType[row.send_type]},{label: '发送时间',prop: 'send_time',minWidth: 130,formatter: (row: any) => Moment.format(Number(row.send_time))},{label: '创建人',prop: 'creator.name'},{label: '所属部门',prop: 'creator',formatter: (row: any) => row.creator?.department?.name || '-'},{label: '已发送成员',prop: 'sent_staff'},{label: '未发送成员',prop: 'unsent_staff'},{label: '已送达客户',prop: 'delivered'},{label: '未送达客户',prop: 'not_delivered'},{label: '创建时间',prop: 'created_at',minWidth: 130,formatter: (row: any) => Moment.format(Number(row.created_at))},{label: '状态',prop: 'plan_status',formatter: (row: any) => planStatusType[row.plan_status]},{label: '操作',prop: 'action',fixed: 'right',width: 250}
];
</script>

看过上一版的朋友们想必都知道上一版的缺陷,内法自定义表头,这次这个版本优化了这个问题,对比上一版能很明显看出我添加了哪一部分,其实很简单的一步操作,很早之前就有了解决方案,但是近期才有时间来更新一下文档

这一期写到这里也就差不多了,有什么意见建议的欢迎提出。


http://www.mrgr.cn/news/11651.html

相关文章:

  • word文档合并样式问题
  • 国产游戏行不行,主要还得“盘”商业模式!
  • 【Docker】Linux系统以及威联通QNAP部署思源笔记的通用教程
  • 一文读懂 DDD领域驱动设计
  • Overleaf中插图需要的pdf图片格式制作方法(python)
  • 【RST示例】Pick and Place Using RRT for Manipulators使用 RRT(快速扩展随机树)进行机械臂的抓取与放置
  • 『功能项目』技能释放【08】
  • 三种通过代码创建矢量文件的方法及例子
  • helm安装jenkins保姆级别
  • 【HTML】模拟二级菜单【附源代码】
  • day-41 零钱兑换
  • 【原创教程】电气制图01:启航EPLAN电气设计
  • 服务器机房与数据中心的区别?
  • 【ORACLE】如何使用EXPLAIN PLAN来分析 listagg() 函数的性能瓶颈?
  • 力扣1862.向下取整数对和
  • layui栅格布局设置列间距不起作用
  • DRF——Filter条件搜索模块
  • 在银河麒麟服务器V10上源码编译安装mysql-5.7.42-linux-glibc2.12-x86_64
  • 【Linux】冯诺依曼体系|操作系统概念
  • 前端技巧——iframe + postMessage进行页面通信