如何动态渲染elementUI table的行和列

  • 需求
  • 实现
  • 注意点
  • 进阶
  • 注意点
  • 写在最后


需求

近日项目中遇到这样一个需求:需要动态渲染一个列表的行和列,官网给出的例子大多是列写死的,行动态生成的,但是如何实现动态渲染行和列呢?后来我查询了一下实现了该功能,如下我将总结一下然后贴上代码。

实现

Talk is cheap,show me the code:

<template>
  <div>
    <div class="retained">
      <el-card>
        <div class="dataList countFont">
          <div>
            <el-table
              border
              :data="dataList"
              style="width: 100%;">
              <el-table-column
                :show-overflow-tooltip="true"
                prop="data"
                width="180">
                <template slot-scope="scope" style="text-align: left">
                  <span>{{scope.row.data ? scope.row.data : '---'}}</span>
                </template>
              </el-table-column>
              <el-table-column
                sortable="custom"
                min-width="180"
                v-for="col in cols"
                :prop="col.prop" :label="col.label">
              </el-table-column>
            </el-table>
            <el-button @click="addCols">
              添加一列
            </el-button>
          </div>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script>

  export default {
    data() {
      return {
        dataList: [
          {
            data: "2019-1-26",
            list0:1,
            list1:2,
            list2: 3,
          },
          {
            data: "2019-1-27",
            list0: 4,
            list1: 5,
            list2: 6,
          },
          {
            data: "2019-1-28",
            list0: 7,
            list1: 8,
            list2: 9,
          },
        ],
        cols: [
          {prop:"list0",label:"第一列"},
          {prop:"list1",label:"第二列"},
          {prop:"list2",label:"第三列"},
        ],
      }
    },
    created() {

    },
    mounted() {
    },
    methods: {
      addCols(){
        //注意:此处"list3"字段名
        this.cols.push({
          prop:"list3",
          label:"第四列"
        })
        this.dataList.forEach(function (value, index) {
          value.list3 = 10+index
        })
      },
    }
  }
</script>

<style lang="scss" scoped>
</style>

注意点

列表的行是根据列cols中的prop去进行识别哪一列的数据从而进行渲染的,所以当你在cols中加入一个对象

this.cols.push({
          prop:"list3",
          label:"第四列"
        })

的时候必须同时动态地向你的行中添加一个与prop同名的key和value:

this.dataList.forEach(function (value, index) {
          value.list3 = 10+index
        })

进阶

有的同学说,我想要同时实现行的自定义怎么办?官网给出的自定义行的代码如下:

<el-table-column
      prop="date"
      label="日期"
      width="180">
         <template slot-scope="scope">
            <span class="dataFont">{{scope.row.date}}</span>
          </template>
</el-table-column>

如果直接放到如上代码中肯定是要报undefined的,因为我们的{{scope.row.date}}这个参数是动态可变的,而如果全部去判断之后显示的话又未免显得过于笨拙了,那么我们可以向父元素看一下,可以看到这个参数:col.prop,没错了,这个就是这个动态的参数,也就相对应原来固定的{{scope.row.date}},好了,话不多说,代码附上:

<template>
  <div>
    <div class="retained">
      <el-card>
        <div class="dataList countFont">
          <div>
            <el-table
              border
              :data="dataList"
              style="width: 100%;">
              <el-table-column
                :show-overflow-tooltip="true"
                prop="data"
                width="180">
                <template slot-scope="scope" style="text-align: left">
                  <span>{{scope.row.data ? scope.row.data : '---'}}</span>
                </template>
              </el-table-column>
              <el-table-column
                sortable="custom"
                min-width="180"
                v-for="col in cols"
                :prop="col.prop" :label="col.label">
                <template slot-scope="scope">
                  <span class="dataFont">{{scope.row[col.prop].num}}</span><br>
                  <span class="percentFont">{{scope.row[col.prop].percent}}</span>
                </template>
              </el-table-column>
            </el-table>
            <el-button @click="addCols">
              添加一列
            </el-button>
          </div>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script>

  export default {
    data() {
      return {
        dataList: [
          {
            data: "2019-1-26",
            list0: {
              num:1,
              percent:.1
            },
            list1: {
              num:2,
              percent:.2
            },
            list2: {
              num:3,
              percent:.3
            },
          },
          {
            data: "2019-1-27",
            list0: {
              num:4,
              percent:.4
            },
            list1: {
              num:5,
              percent:.5
            },
            list2: {
              num:6,
              percent:.6
            },
          },
          {
            data: "2019-1-28",
            list0: {
              num:7,
              percent:.7
            },
            list1: {
              num:8,
              percent:.8
            },
            list2: {
              num:9,
              percent:.9
            },
          },
        ],
        cols: [
          {prop:"list0",label:"第一列"},
          {prop:"list1",label:"第二列"},
          {prop:"list2",label:"第三列"},
        ],
      }
    },
    created() {

    },
    mounted() {
    },
    methods: {
      addCols(){
        //注意:此处"list3"字段名
        this.cols.push({
          prop:"list3",
          label:"第四列"
        })
        this.dataList.forEach(function (value, index) {
          value.list3 = {
            num:10+index,
            percent:(10+index)/10
          }
        })
      },
    }
  }
</script>

<style lang="scss" scoped>
</style>

注意点

此处的“list3”我写成了固定的,但其实这是可以变更的,可以把后端返回给你的数据遍历然后动态添加,这个表格的行和列也就可以动态生成了,我在这里就先只提供这个基础方法了,如何使用看得看大兄弟你自己啦。如果有遇到什么问题,可以留言给我。