如何使用一个element-ui Table表格
⭐准备工作
本篇会介绍: element-ui Table的基本使用,看我是如何一步步把数据装进去,实现其中各个筛选功能,并最终实现简单的组件封装
之所以说是简单的封装,是因为我不会像其他教程一样,将整个表解耦封装为组件,适用于多种情况,我这里只进行简单的整理,只能做到针对我当前项目,可以传入固定格式数据,生成表格
之所以说是新手向,是因为我当时想要学习封装element组件时,很多大佬的帖子都写得很厉害,很复杂,将很多功能都装了进去,对于我这种新手来说,大多数都是我用不到的,而且也看不懂其中思路,所以我这里提供一篇完完全全纯新手的简单封装,给初学的小伙伴们提供一些简单的封装思路~
所以我们需要前置知识:
- Vue2的基本使用
- Elemen-ui的引入和基本使用方式
⭐开始
我们先说需求:
我请求回来一堆json数据,它长这个亚子:
{
"success": true,
"code": 200,
"msg": "success!",
"data": [
{
"id": 1,
"title": "测试标题",
"summary": "博客系统文章测试",
"commentConunts": 0,
"viewCounts": 0,
"weight": 1,
"createDate": "2023-04-30 13:48",
"author": "何小幸",
"tags": [
{
"id": 1,
"tagName": "后端"
}
]
}
]
}
里面的data部分时我要在页面上进行展示的内容
根据Element-ui Table需要收到的数据格式,我将数据转换为以下形式:
{
"author": "何小幸"
"createDate": "2023-04-30 13:48"
"summary": "博客系统文章测试"
"tags": ["后端"]
"title": "测试标题"
}
挑挑选选,由于我的数据中有标签项,我选中了这个表格:
这个表格还可以通过标签右侧的小三角,实现根据标签筛选数据,也可以通过日期旁的三角设置日期顺序或倒序,以及根据日期来筛选数据!
选好表格,我们直接把代码拿过来!
代码拿到手后,我们先一步一步来,我们先不进行封装,先正常进行数据展示,这样它的数据部分就变成了这样:
<el-table-column
prop="title"
label="标题"
width="180">
</el-table-column>
<el-table-column
prop="author"
label="作者"
width="180">
</el-table-column>
<el-table-column
prop="summary"
label="摘要">
</el-table-column>
<el-table-column
prop="createDate"
label="日期"
sortable
width="180"
column-key="date"
:filters="dateFilters"
:filter-method="filterHandler"
>
</el-table-column>
根据我们需要的数据,我们先手动将各列做出来
标签列略为复杂,我们从最初开始讲起:
<el-table-column
prop="tag"
label="标签"
width="100"
:filters="[{ text: '家', value: '家' }, { text: '公司', value: '公司' }]"
:filter-method="filterTag"
filter-placement="bottom-end">
<template slot-scope="scope">
<el-tag
:type="scope.row.tag === '家' ? 'primary' : 'success'"
disable-transitions>{{scope.row.tag}}</el-tag>
</template>
</el-table-column>
这是刚从官网拿回来的代码,里面各部分含义如下:
-
prop为传入的标签字符串
-
label为显示的表头
-
width就不多说啦~宽度嘛
-
:filters表示我们可以传入的标签列表,起到了一个规范的作用,如果传入了filter以外的内容,就显示不出来了哦!
-
:filter-method表示筛选标签的方法,我们点击表头右侧小三角,选中标签就可以进行筛选的原因就是它!
-
filter-placement顾名思义,就是摆放位置啦
-
接下来是template标签,其中定义了slot-scope,通过它,我们可以获得这一行的各种数据,例如:
- scope.row.tag能获取到我们在上方props中传入的tag
- 还可以用来获取row、column、$index以及store中的数据,在这里不再赘述,有兴趣的话自己下来打印一下就懂啦!
-
:type定义了显示的样式(标签的蓝色和绿色)
-
{{scope.row.tag}} 才是显示在我们页面上的标签数据
懂了这些我们就可以开工啦!
🌙标签中的长数据都写到data中
比如:
- 标签列的
:filters="[{ text: '家', value: '家' }, { text: '公司', value: '公司' }]" - 日期列的
:filters="[{text: '2016-05-01', value: '2016-05-01'}, {text: '2016-05-02', value: '2016-05-02'}, {text: '2016-05-03', value: '2016-05-03'}, {text: '2016-05-04', value: '2016-05-04'}]"
data() {
return {
tagFilters: [
{ text: '前端', value: '前端' },
{ text: '后端', value: '后端' }
],
dateFilters:[
{text: '2016-05-01', value: '2016-05-01'},
{text: '2016-05-02', value: '2016-05-02'},
{text: '2016-05-03', value: '2016-05-03'},
{text: '2016-05-04', value: '2016-05-04'}
],
}
},
标签中直接调用::filters="tagFilters"
同时,我们把所有要展示的数据也存放在data中,但如果你的数据是从父组件异步请求回来,再通过props返回给表格组件的话,表格是不会有响应的,我们就需要在watch中对数据进行监听:
//dataList是Props中的数据名,tableList是data中传给表格的数据名
watch: {
dataList() {
this.tableList = this.dataList
console.log(this.tableList)
}
}
多个标签的展示
要展示不确定数目的多个标签,就要使用v-for啦,那给谁加呢?
上面我们分析出来,el-tag中的{{tag}}才是展示的数据来源,我们就给它外层加一个div,然后v-for循环展示文章的tag:
<div v-for="(tag,index) in scope.row.tags"
:key="tag"
class="tagItem">
<el-tag
:type="index%2===0 ? 'primary' : 'success'"
disable-transitions
>{{tag}}</el-tag>
</div>
这样,它循环的就是scope.row.tags,而scope.row的tags从哪里来呢?
当然是这一列的prop标签上的tags,所以我们这列的prop标签也要进行对应修改:
prop="tags"
我们把:type也做一下修改,让他相邻的两个标签不重样!
这样基本的数据展示就做好啦~
🌙日期及标签的筛选
想实现点击小三角进行日期和标签的筛选功能?跟着我走!
我们先来做日期筛选:
官网范例中日期筛选是通过这个方法:
filterHandler(value, row, column) {
const property = column['property'];
return row[property] === value;
}
参数都是element-ui自动传入的,column['property']表示的是日期的key,比如我的数据中日期为:createDate: 2023-04-30 13:48,他这里就获取到了createDate
这样一来,row[property]其实就是row[createDate],获取到了该行的日期,value是我们选中要筛选的日期,两者做个比较,如果相等,返回true,那这行就会被保留,如果为false,那么表示这行不符合我们的筛选要求,不予展示!
而我们下拉小三角看到的日期是从哪里来的呢?
仔细观察,是不是和我们之前写到Data中的日期一样!
也就是说,筛选的选项是从我们传入的filter中取得的
这下可麻烦了!这里数据都是写死的,那么如果我们要新传入一个数据,岂不是还要手动去data中修改吗?
这里,我们就要做一些处理了——收到传入的数据dataList后,将日期信息提取出来,存到dateFilters中,这样我们就可以动态扩充日期选项表了:
//在dataList的watch中,即刚收到props的时候进行日期处理
for(let item of this.dataList) {
//拆分出日期放到dateFilters中
this.dateFilters.push({
text: item.createDate,
value: item.createDate
})
}
日期筛选做完了,标签筛选也是一样的呀!
点击小三角展示出来的标签是tagFilters中的数据,我们同样在收到传入的dataList数据后,将tag信息提取出来,存到tagFilters中:
for(let item of this.dataList) {
//拆分出tag放到tagFilters中
for(let tag of item.tags) {
if(this.tagFilters.indexOf(tag)===-1) {
this.tagFilters.push({
text: tag,
value: tag
})
}
}
}
要注意判断tagFilters中是否已经存在对应的tag,如果已经存在,那么就不用重复保存啦!
日期和标签的数据转换可以写在一起:
for(let item of this.dataList) {
//拆分出日期放到dateFilters中
this.dateFilters.push({
text: item.createDate,
value: item.createDate
})
//拆分出tag放到tagFilters中
for(let tag of item.tags) {
if(this.tagFilters.indexOf(tag)===-1) {
this.tagFilters.push({
text: tag,
value: tag
})
}
}
}
这下我们的简易表格就做好啦!
在父组件中只需要引入后写标签,再传入数据即可!
<Pagination :data-list="listDate"/>
整个封装好的表格:
<template>
<div>
<el-button @click="clearFilter">清除所有过滤器</el-button>
<el-table
ref="filterTable"
:data.sync="tableList"
style="width: 100%">
<el-table-column
prop="title"
label="标题"
width="180">
</el-table-column>
<el-table-column
prop="author"
label="作者"
width="180">
</el-table-column>
<el-table-column
prop="summary"
label="摘要">
</el-table-column>
<el-table-column
prop="createDate"
label="日期"
:sortable="true"
width="180"
column-key="date"
:filters="dateFilters"
:filter-method="filterHandler"
>
</el-table-column>
<el-table-column
prop="tags"
label="标签"
width="300"
:filters="tagFilters"
:filter-method="filterTag"
filter-placement="bottom-end">
<template slot-scope="scope">
<div v-for="(tag,index) in scope.row.tags"
:key="tag"
class="tagItem">
<el-tag
:type="index%2===0 ? 'primary' : 'success'"
disable-transitions
>{{tag}}</el-tag>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
tagFilters: [],
dateFilters:[],
tableList:[]
}
},
props:{
dataList:{
type: Array
}
},
methods: {
resetDateFilter() {
this.$refs.filterTable.clearFilter('date');
},
clearFilter() {
this.$refs.filterTable.clearFilter();
},
filterHandler(value, row, column) {
const property = column['property'];//取到该行的key:createDate
console.log(column['property'])
return row[property] === value;
},
filterTag(value, row) {
console.log(row.tags.indexOf(value))
return row.tags.indexOf(value)!==-1;
},
},
watch: {
dataList() {
this.tableList = this.dataList
for(let item of this.dataList) {
//拆分出日期放到dateFilters中
this.dateFilters.push({
text: item.createDate,
value: item.createDate
})
//拆分出tag放到tagFilters中
for(let tag of item.tags) {
if(this.tagFilters.indexOf(tag)===-1) {
this.tagFilters.push({
text: tag,
value: tag
})
}
}
}
}
}
}
</script>
<style>
.tagItem {
display: inline-block;
margin-right: 5px;
}
</style>
传入的数据结构如文章开头写的那样:
{
"author": "何小幸"
"createDate": "2023-04-30 13:48"
"summary": "博客系统文章测试"
"tags": ["后端"]
"title": "测试标题"
}
⭐结语
这样简易的封装受局限很大,只能展示在表格中规定的样式,不能增,不能减,不能在外部调整其中某列的表现形式,但好处就是易于理解,方便初学者进行学习以及个人小项目的简单实用。
当以上内容都掌握后,就可以去学习表格的整体封装,在整体封装中,表格的表头、表头的表现样式等都是由我们传入的配置信息来决定及动态生成的,其实思路很简单,v-for加到列标签上,循环传入的表头信息配置项即可,再根据传入的配置决定是否开启某个功能,这样实现起来就复杂得多,但在用起来也更加灵活,但也不需要过度封装,符合我们自己项目组件的才是最好的!