vue3 二次封装element-plus 表格组件

由于项目中会频繁的使用表格,会出现非常多的重复代码,所以决定对element-plus的table组件进行封装,尽量避免代码冗余。代码如下:

1.在components文件下新建Table/index.vue文件

<template>
	<el-table v-loading="listLoading" :data="tableData" element-loading-text="Loading" fit border highlight-current-row
		:max-height="maxHeight">
		<el-table-column v-for="(item,index) in tableHeader" :key="index" :prop="item.prop" align="center"
			:label="item.label" :min-width="item.minHeight">
			<template #default="scope">
				<div v-if="item.btn"> 
                    //操作栏的按钮判断
					<el-button v-for="(k,index) in item.btn" :key="index" type="text" size="mini"
						@click="k.func(scope.$index, scope.row)">{{k.name}}</el-button>
				</div>
				<div v-else>
					<span v-if="!item.formatData">
                        //日期拼接并且只显示年月日
						<span
							v-if="item.isDate == true">{{ repString(scope.row[item.prop[0]]) }}-{{ repString(scope.row[item.prop[1]])}}</span>
						<span v-else>{{ scope.row[item.prop] }}</span>
					</span>
					<span v-else>
                        //根据不同状态显示不同的文字颜色
						<el-link v-if="item.isline == true" :type="item.lineType(scope.row[item.prop])"
							:underline="false">{{ item.formatData(scope.row[item.prop]) }}</el-link>
						<span v-else>{{ scope.row[k.prop] }}</span>
					</span>
				</div>
			</template>
		</el-table-column>
	</el-table>
</template>

<script>
	export default {
		props: {
			tableData: {
				type: Array,
				default: () => []
			},
			tableHeader: {
				type: Array,
				default: () => []
			},
			listLoading: {
				type: Boolean,
				default: false
			},
			maxHeight: {
				type: String,
				default: ''
			},
		},
		setup(props) {
            //对日期进行截取
			function repString(val) {
				return val.substr(0, 10)
			}
			return {
				repString
			}
		}
	}
</script>

<style>
</style>

2.在组件中使用

<template>
	<div class="app-container">
		<Ltable :tableData='list' :tableHeader="tableHeader" :listLoading="listLoading" :maxHeight='maxHeight'></Ltable>
	</div>
</template>

<script lang="ts" setup>
	import {votethemes} from "@/api/planning";
	import Ltable from '@/components/LTable/index.vue'
	import {
		ref,
		reactive,
		nextTick,
		onMounted,
		toRefs
	} from 'vue'
	import {
		useRouter
	} from 'vue-router'
	import {
		ElMessage
	} from 'element-plus'

	const router = useRouter()
	const state = reactive({
		list: [],
        page: {},
		listLoading: false,
		tableHeader: [{
				prop: 'id',
				label: '编号',
				minHeight: '50px',
			},
			{
				prop: 'votethemeTitle',
				label: '主题名称',
				minHeight: '150px',
			},
			{
				prop: 'userName',
				label: '发布人',
				minHeight: '80px'
			},
			{
				prop: ['votethemeStart', 'votethemeEnd'],
				label: '活动时间',
				minHeight: '210px',
				isDate: true
			},
			{
				prop: 'worksCount',
				label: '参与作品',
				minHeight: '80px'
			},
			{
				prop: 'votethemeStatus',
				label: '状态',
				minHeight: '80px',
				formatData: (val) => {
					return val == 1 ? '未开始' : val == 2 ? '进行中' : val == 3 ? '已结束' : ''
				},
				isline: true,
				lineType: (val) => {
					return val == 1 ? 'success' : val == 2 ? 'primary' : val == 3 ? 'info' : ''
				}
			},
			{
				prop: 'btn',
				label: '操作',
				minHeight: '120px',
				btn: [{
						name: '查看',
						func: handleLook
					},
					{
						name: '编辑',
						func: handleEdit
					}
				]
			}
		],
		maxHeight: 'calc(100vh - 322px)',
	})
	const {
		list,
        page,
		listLoading,
		tableHeader,
		maxHeight,
	} = toRefs(state)
	const fetchData = () => {
		state.listLoading = true;
		votethemes(state.page).then((response) => {
			state.list = response.data.list;
		});
	}
	onMounted(() => {
		fetchData()
	})

	function handleEdit(index, row) {
		console.log(row)

	}
	function handleLook(index, row) {
		router.push({
			path: "detail?id=" + row.id
		});
	}

</script>
<style>

</style>

效果

vue3 二次封装element-plus 表格组件

上一篇:python将知识图谱的节点关系(CSV或其他格式)转换成Echarts所需的json格式


下一篇:数据分析进阶-Excel自动化工具包openpyxl的基础使用