如何使用一个element-ui Table表格

1,300 阅读4分钟

如何使用一个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": "测试标题"
}

挑挑选选,由于我的数据中有标签项,我选中了这个表格:

BaseTable.png

这个表格还可以通过标签右侧的小三角,实现根据标签筛选数据,也可以通过日期旁的三角设置日期顺序或倒序,以及根据日期来筛选数据!

选好表格,我们直接把代码拿过来!

代码拿到手后,我们先一步一步来,我们先不进行封装,先正常进行数据展示,这样它的数据部分就变成了这样:

<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也做一下修改,让他相邻的两个标签不重样!

这样基本的数据展示就做好啦~

BasicShow.png

🌙日期及标签的筛选

想实现点击小三角进行日期和标签的筛选功能?跟着我走!

我们先来做日期筛选:

官网范例中日期筛选是通过这个方法:

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加到列标签上,循环传入的表头信息配置项即可,再根据传入的配置决定是否开启某个功能,这样实现起来就复杂得多,但在用起来也更加灵活,但也不需要过度封装,符合我们自己项目组件的才是最好的!