您现在的位置是:网站首页> 编程资料编程资料

Vue业务组件封装Table表格示例详解_vue.js_

2023-05-24 447人已围观

简介 Vue业务组件封装Table表格示例详解_vue.js_

前言

这个系列主要是分享自己在工作中常用到的业务组件,以及如何对这些组件进行有效的封装和封装的思路。注:都是基于element ui进行二次封装。

封装组件的基本方法就是通过props和emit进行父子组件的传值和通信。利用插槽、组件等去增加组件的可扩展性和复用性。

Table组件介绍

用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。table组件常用于后台管理系统,基本上是后台管理系统中使用频率最高的组件了,一个table组件具有最基本的功能就是crud。

基本的table

Table组件封装思路

了解element Table组件代码

这里以最基本的Table代码为例进行分析:

table样式

根据基本的Table代码,我们可以知道:

  • Table渲染的数据是一个数组,数组的每一项包含了每一列的信息,然后绑定到el-table的data属性里面。
  • el-table-column为Table一行中每列的内容,一行有多少列,就写多少个el-table-column。
  • 每个el-table-column中绑定了prop、label属性,他们分别对应data数据里所渲染出来的内容和每列的表头文字,注意prop的值一定要与tableData里的对象属性相同。

Table组件如何去封装

通过分析Table代码我们可以把el-table-column里面绑定的属性抽离出一个配置文件,通过对配置文件的遍历得到所有el-table-column。

配置文件代码实现

新建LTable组件

我们在components文件夹下新建一个LTable表示我们封装的Table组件。基于Table组件的基本代码,我们写下LTable下代码内容:

在组件中我们需要父组件传入一个columnList,也就是前面我们说的配置文件,table的数据我们在LTable里获取,不用父组件传递过来。这样做的好处是:将通过接口获取table数据统一在LTable管理,减少父组件获取接口数据然后传递给LTable的重复代码逻辑。相应我们需要传递请求数据的接口地址。

配置文件

新建一个配置文件tableConfig.js,导出文件内容,然后再需要用到的页面引入。

export const tableConfig = { columnList: [ { label: "日期", prop: "date", sortable: true //对表格进行排序 }, { label: "图片", //文字 prop: "imgSrc", //渲染数据对应的属性 width: "180" //每列对应宽度 }, { label: "姓名", prop: "name" }, { label: "地址", prop: "address" } ], showIndexColumn: true, //是否显示table索引 showSelectColumn: true, //是否显示选择多行 requestUrl: "api/getData" //接口请求地址 }; 

页面内容:

table效果

这样,一个基本的Table封装就完成了,可以看到我们在页面中的代码是非常少的,只有引入了组件,然后将配置文件绑定到组件上就可以了。

不过目前写的配置都是非常简单的,如果遇到复杂的表格内容,我们怎么办?

配置插槽

刚刚完成的小案例我们发现图片是直接显示了地址,那我们想展示图片怎么办,一般表格还会有操作列,我们怎么展示出来呢?

这种我们不能直接渲染数据,而是需要转换,比较灵活得到我们想要的的内容就需要用到插槽了。

首先我们需要在配置文件增加插槽的选项,我们这里取名slotName:

columnList: [ { label: "日期", prop: "date", Sortable: true }, { label: "图片", prop: "imgSrc", width: "180", slotName: "img" }, { label: "姓名", prop: "name" }, { label: "地址", prop: "address" }, { label: "操作", prop: "action", slotName: "action" } ], 

对应的LTable组件里面的渲染逻辑我们也需要调整,改为有插槽和没有插槽两种情况去渲染。表格里的插槽有些在所有表格里面都会用到比如操作,这种我们就当做默认插槽,写在LTabl里面。

不是每个表格都需要用到插槽就是动态插槽了,放在对应的页面里。

LTable增加插槽的代码:

页面里面动态插槽内容:

渲染出来的表格:

带有插槽表格

这样,我们就通过配置文件搭配插槽完成了Table组件的封装,我们可以自由灵活的显示我们表格里的内容。但同时,我们也发现,当我们LTable组件里涉及到的插槽越来越多的时候,里面的代码也会越来越多。随着我们的项目越来越复杂,需要的插槽可能有几十个甚至上百个,使用插槽的方式进行封装开始显示出了很多问题。我们该如何对这种情况进行优化呢?

动态组件

解决插槽存在的问题

针对上面提出的问题,我从自动化的角度进行了思考,放弃了大量使用插槽,改用组件代替插槽的形式进行优化。将插槽的类型进行汇总,分别定义不同类型的组件去替换插槽,大大减少了由插槽产生的代码。

代码实现

首先在配置文件里面添加了type属性,表示它对应哪个动态组件。还添加了cb回调函数,主要处理对数据的格式进行转化。

export const tableConfig = { columnList: [ { type: "text", label: "日期", prop: "date", width: "180" }, { type: "image", label: "图片", prop: "imgSrc", width: "180" }, { type: "text", label: "姓名", prop: "name" }, { type: "function", label: "性别", prop: "sex", sortable: true, cb: data => { return data == 1 ? "男" : "女"; } }, { type: "input", label: "地址", prop: "address" }, { type: "slot", label: "操作", prop: "action", slotName: "actions" } ], showIndexColumn: true, showSelectColumn: true, requestUrl: "api/getData" }; 

然后在LTable组件里面做自动化处理,这里需要用到Node里面的require.context方法,他会递归获取相应文件夹下的对应类型文件。

所以我们还需要在相应文件夹下面创建相应的组件,这里我是在components文件夹下创建了control文件夹,control文件夹下放我们对应需要渲染的组件,这里我创建了四个,function、image、input、text,分别对应内容需要转化、图片展示、最基本文字、输入框。根据具体的业务创建不同的组件即可。

control文件夹

我们需要用require.context方法在LTable组件里拿到control文件夹下的所有组件。

const modules = {}; const files = require.context("../control", true, /\index.vue$/); files.keys().forEach(item => { const name = item.split("/")[1]; modules[`com-${name}`] = files(item).default; }); console.log(modules, 'modules'); 

打印modules

注册组件:

components: { ...modules }, 

我们通过动态组件的方式,根据我们要渲染的表格内容去加载不同的组件:

页面里面的内容: