关于el-table的二次封装及使用
table组件
<template><el-table ref="tableComRef" :data="tableData" border style="width: 100%"><el-table-column v-if="tableHeaderList[0]?.type === 'selection'" type="selection"></el-table-column><el-table-column label="序号" width="80" type="index" :index="indexMethod"></el-table-column><el-table-columnv-for="(item, index) in (tableHeaderList[0]?.type === 'selection' ? tableHeaderList.slice(1) : tableHeaderList)":key="index":index="indexMethod":width="item.width"align="center":prop="item.prop":property="item.property":type="item.type":label="item.label":show-overflow-tooltip="true"><template #default="scope">// 展示内容判断自定义渲染<div v-if="item.render" class="center" v-html="item.render(scope.row)"></div>// 默认渲染<div v-else class="center" v-html="scope.row[item.property]"></div></template><template v-if="item.custom" #default="scope">// 使用自定义列<div v-if="item.isSlot"><slot name="mySlot" :data="scope.row"></slot></div>// 每一行数据操作列内容都相同时使用下方代码<div v-else><div class="operationAll center cursor-pointer"><div class="center flex-1 cursor-pointer"><divv-for="(customData, index) in item.customList1":key="index":class="customData.class":title="customData.name"class="operation center flex-1"@click="clickHandle(customData.event, scope.row, scope.$index)"><p :style="{ width: customData.width, height: customData.height }"><img :src="customData.imgUrl" alt="" /></p><p :style="{ color: customData.color }">{{ customData.name }}</p></div></div></div></div></template></el-table-column></el-table>
</template><script setup>
import { ref, getCurrentInstance, onMounted, nextTick, computed } from 'vue';
const ins = getCurrentInstance();
const bus = ins.appContext.config.globalProperties.$bus;
const props = defineProps({tableHeaderList: {type: Array,default: [],},tableData: {type: Array,default: [],},showTooltip: {type: Boolean,default: false,},pages: {type: Object,default: {pageSize: 10,currentPage: 1,},},
});const page = computed(() => props.pages);// 初始化tableindex
const indexMethod = (index) => {return page.value.pageSize * (page.value.currentPage - 1) + (index + 1);
};
父组件
<table-list:table-header-list="tableHeader":data="softManageTableData":show-tooltip="true":pages="softManagePage"@selection-change="softManageSelect"><template v-slot:mySlot="{ data }"><div class="end flex-1 cursor-pointer"><divv-for="(item, index) in operationBtns":key="index":class="item.class":title="item.name"class="operation center"@click.stop="emitClick(item,data)">// 公共项<div v-if="item.isCommon" class="center mr-[10px]"><p :style="{ color: item.color }">{{ item.name }}</p></div><div v-else>// 独有项<div v-if="data.relSource === item.isLocalUnit" class="center"><p :style="{ width: item.width, height: item.height }"><img :src="item.imgUrl" alt="" /></p><p :style="{ color: item.color }">{{ item.name }}</p></div></div></div></div></template></table-list>
script部分展示
// table header文字数据
const tableHeader = ref([{type: 'selection',},{type: '',width: '',property: 'name',label: '名称',hasIcon: true,// 自定义渲染render: (val) => {return `<div class="startX"><img src="${val.iconUrl}" alt="" class="w-[32px] h-[32px] softIcon"><p class="ml-[12px]">${ val.name }</p></div>`}},{type: '',width: '100',property: 'type',label: '类型',isSoftType: true,render: (val) => {return val.type === 'B' ? 'B' : 'C';}},{type: '',width: '',property: 'clasName',label: '分类',},{type: '',width: '100',property: 'source',label: '来源',render: (val) => {return val.relSource === '1' ? '外部' : '自有';}},{type: '',width: '100',property: 'version',label: '版本',},{type: '',width: '',property: 'releaseTime',label: '发布时间',},{type: '',width: '100',property: 'person',label: '联系人',},{type: '',width: '',property: 'contact',label: '联系方式',},{type: '',width: '',property: 'status',label: '状态',render: (val) => {let status = '';switch (val.status) {case 'wait':status = '<div class="waitUp center logs"><p></p>1</div>'break;case 'enable':status = '<div class="enableUp center logs"><p></p>启用</div>'break;case 'disable':status = '<div class="disableUp center logs"><p></p>禁用</div>'break;default:break;}return status;}},{type: '',width: '350',property: '',label: '操作',custom: true,// 操作栏需要根据当前数据自定义展示isSlot: true,// 操作栏每一项都一致时可用这个customList1: [{name: '移除',type: 'primary',event: 'removeItem',class: 'removeItem',isShowName: false,width: '23px',height: '24px',imgUrl: new URL('/src/assets/removeIcon.png', import.meta.url).href,},{name: '编辑',type: 'primary',event: 'editItem',class: 'editItem',isShowName: false,width: '23px',height: '24px',imgUrl: new URL('/src/assets/softDetailEditIcon.png', import.meta.url).href,},{name: '详情',type: 'danger',event: 'detailItem',class: 'detailItem',isShowName: false,width: '23px',height: '26px',imgUrl: new URL('/src/assets/detailIcon.png', import.meta.url).href,},],},
]);// 操作栏自定义事件
const emitClick = (item,data) => {if(item.event && typeof item.event === 'function') {// 这里将事件转发了一下,没有直接调用,直接调用会抛出无限递归的错误item.event(data,item);} else {ElMessage.error('点击事件定义有误');}
}// 自定义操作栏
// 本单位操作按钮相关 显示为true 隐藏为false
const operationBtns = ref([{name: '启用',type: 'primary',event: openShareItem,class: 'openShareItem',isCommon: true,width: '23px',height: '24px',imgUrl: new URL('/src/assets/softDetailEditIcon.png', import.meta.url).href,},{name: '禁用',type: 'primary',event: openShareItem,class: 'closeShareItem',isCommon: true,width: '23px',height: '24px',imgUrl: new URL('/src/assets/softDetailEditIcon.png', import.meta.url).href,},{name: '编辑',type: 'primary',event: editItem,class: 'editItem',isLocalUnit: '2',isCommon: false,width: '23px',height: '24px',imgUrl: new URL('/src/assets/softDetailEditIcon.png', import.meta.url).href,},{name: '删除',type: 'primary',event: removeItem,class: 'removeItem',isLocalUnit: '2',isCommon: false,width: '23px',height: '24px',imgUrl: new URL('/src/assets/removeIcon.png', import.meta.url).href,},{name: '移除',type: 'danger',event: moveClearItem,class: 'moveClearItem',isLocalUnit: '1',isCommon: false,width: '23px',height: '26px',imgUrl: new URL('/src/assets/detailIcon.png', import.meta.url).href,},{name: '详情',type: 'danger',event: detailItem,class: 'detailItem',isLocalUnit: '2',isCommon: true,width: '23px',height: '26px',imgUrl: new URL('/src/assets/detailIcon.png', import.meta.url).href,},
])
效果图