关于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-column
v-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">
<div
v-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">
<div
v-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,
},
])
效果图