打工日记-Vue3+Ts二次封装el-table

el-table是elementUI中的表格组件,在后台把管理系统中,也是一个比较常用的组件,目前有一个比较好的开源项目ProTable,这个项目做的很好,集成了搜索,表格,分页器功能很强大。但在我的实际使用中也有一些需要更改的地方,因此,我也尝试着封装自己的table组件。

需求

  • 定制化:这是最基本的要求,每个表格的表头都是不一样的,封装table组件,首先就要满足它的定制化输入。
  • 表格操作列
  • 末尾添加一行

制作

定制化

让用户能够自定义配置列表项

思路

父子通信,将父组件配置好的columns传递给子组件,然后使用v-for遍历生成表格cell。

实现

首先我们需要在父组件得到传递过来的参数,使用defineProps接收

typescript 复制代码
const props = defineProps({
	data: {
		type: Array,
		default: () => []
	},
	config: {
		type: Object,
		default: () => ({})
	}
})

在这里data的就是将来我们接收tabledata的,config则用来接收columns配置

将接收到的数据进行渲染

html 复制代码
<el-table-column v-for="(item, index) in config.columns" :key="index"  :label="item.label" :width="item.width">
			<template #default="{ row }">
				<el-input class="inputBox" v-if="item.type === 'txt'" v-model="row[item.prop]" />
			</template>
</el-table-column>

似乎这样,就封装好了一个表格组件,但是实际使用中一点代码提示都没有,我们根本不知道需要组件预留的方法,我们似乎都没怎么使用到TS,因此我们来改造一下代码,为config添加一个config配置文件

typescript 复制代码
type Type = "txt" | "tag";

export interface TableColumns<U> {
	type: Type;
	prop: keyof U;
	label: string;
	width?: number;
}

export interface TableConfigTest<T> {
	columns: TableColumns<T>[];
}

在这个配置文件中声明了两个TS接口,明确columns该怎么写,并且需要接收一个参数,将来使用组件时,将tabledata的类型接口传进来,就会自动解析prop(使用keyof实现,keyof 是 TypeScript 中的一个关键字,用于获取某个类型的所有属性名组成的联合类型)。

现在来重写一下congig,使用类型断言缩小config的类型

typescript 复制代码
config: {
		type: Object as PropType<TableConfigTest<Object | any>>,
		default: () => ({})
	}

这样我们就完成组件的第一个需求,定制化。

表格操作列

因为我只需要一个删除行的操作,所以这里使用了一个简单的方法,就是在组件中直接书写操作

html 复制代码
<el-table-column fixed="right" label="操作" width="120">
			<template #default="{ row }">
				<el-button type="danger" icon="el-icon-delete" @click="deleteRow(row)"> 删除 </el-button>
			</template>
</el-table-column>

然后将删除方法实现

typescript 复制代码
const deleteRow = (row: any) => {
	const index = props.data.indexOf(row);
	if (index > -1) {
		props.data.splice(index, 1);
	}
};

使用演示

html 复制代码
<MyTable :config="tableConfigEdu" :data="tableDataEdu" :border="true" />
<script setup lang="ts">
interface TableDataTrain {
	startDate: string;
	endDate: string;
	address: string;
	content: string;
}
const tableConfigTrain = ref<TableConfigTest<TableDataTrain>>({
	columns: [
		{
			type: "txt",
			prop: "startDate",
			label: "开始日期",
			width: 200
		},
		{
			type: "txt",
			prop: "endDate",
			label: "截止日期",
			width: 200
		},
		{
			type: "txt",
			prop: "address",
			label: "地点"
		},
		{
			type: "txt",
			prop: "content",
			label: "内容"
		}
	]
});
const tableDataTrain = ref<TableDataTrain[]>([{ startDate: "", endDate: "", address: "", content: "" }]);
</script>

封装组件是为了更好的工作,随着工作的需求增加,会不断增加组件的功能,同时也会更新文档。

gitee仓库

相关推荐
火柴就是我几秒前
每日见闻之Three.js 根据官方demo 理解相机位置
前端
JosieBook10 分钟前
【web应用】基于Vue3和Spring Boot的课程管理前后端数据交互过程
前端·spring boot·交互
GDAL16 分钟前
SWC 深入全面讲解
typescript·swc
刘大猫.17 分钟前
npm ERR! cb() never called!
前端·npm·node.js·npm install·npmm err·never called
咔咔一顿操作21 分钟前
常见问题三
前端·javascript·vue.js·前端框架
上单带刀不带妹22 分钟前
Web Worker:解锁浏览器多线程,提升前端性能与体验
前端·js·web worke
电商API大数据接口开发Cris38 分钟前
Node.js + TypeScript 开发健壮的淘宝商品 API SDK
前端·数据挖掘·api
还要啥名字41 分钟前
基于elpis下 DSL有感
前端
一只毛驴1 小时前
谈谈浏览器的DOM事件-从0级到2级
前端·面试
用户8168694747251 小时前
封装ajax
前端