文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Element怎么实现动态表格

2023-06-20 19:22

关注

本篇内容介绍了“Element怎么实现动态表格”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

目录

【代码背景】

有这样一个业务需求场景,有大概十几张表归属于某个类别,用户希望在同一个页面,通过选择不同的查询指标展示不同的表格,这些表的表头样式类似但是又不完全相同,怎么做呢?

到目前为止所有基于Element UI的表格样式都是直接在页面写死的,像官方这样:

<el-table :data="tableData" >    <el-table-column prop="date" label="日期" width="180"></el-table-column>    <el-table-column prop="name" label="姓名" width="180"></el-table-column>    <el-table-column prop="address" label="地址"></el-table-column></el-table>

要解决上述问题,最简单暴力的方式是为每个表写一个单独组件,然后通过select框触发事件切换不同组件路由渲染页面,当然这种方式很笨,也不符合代码复用的基本原则,所以为了偷懒,为了坚守代码复用的基本原则,开始思考有没有更好的方式来解决这个问题。

仔细观察这个<el-table>,表格数据是通过:data绑定的,表格头部数据则是通过<el-table-column>标签展示的,表头数据是不是也可以通过某种传参的方式结合v-for来渲染<el-table-column>的具体数据呢?在度娘的帮助下,果然有大佬已经这样做了,实现了动态表格,参考链接挂在最底下了哦,在此特别感谢免费分享知识的大佬们,知识无价,学无止境。

现将本项目的具体实现代码记录如下,完善了一些代码的注解,尝试帮助理解。

【代码实现】

#1# -> 代码复用的基础是你需要一个可复用的组件

在/components/Table文件夹下新建两个组件

DynamicTable.vue

<template>  <!-- 动态展示表格 -->  <el-table :data="tableData" border stripe :height="height" @row-click="handleRowClick">    <!-- v-for 循环取表头数据 -->    <template v-for="item in tableHeader">      <table-column v-if="item.children && item.children.length" :key="item.id" :column-header="item" />      <el-table-column v-else :key="item.id" :label="item.label" :prop="item.prop" align="center" />    </template>  </el-table></template>
<script>  import TableColumn from '@/components/Table/TableColumn'   export default {    name: 'DynamicTable',    components: {      TableColumn    },    props: {      // 表格的数据      tableData: {        type: Array,        required: true      },      // 多级表头的数据      tableHeader: {        type: Array,        required: true      },      // 表格的高度      height: {        type: String,        default: '300'      }    },    methods: {      // 行点击事件      handleRowClick (row, column, event) {        // console.log(row)        // console.log(column)        // console.log(event)        // 通知调用父组件的row-click事件        // row作为参数传递过去        this.$emit('row-click', row)      }    }  }</script>

TableColumn.vue

<template>  <el-table-column    :label="columnHeader.label"    :prop="columnHeader.label"    align="center"  >    <!--columnHeader对应:column-header-->    <template v-for="item in columnHeader.children">      <tableColumn        v-if="item.children && item.children.length"        :key="item.id"        :column-header="item"      />      <el-table-column        v-else        :key="item.name"        :label="item.label"        :prop="item.prop"        align="center"      />    </template>  </el-table-column></template> <script>  export default {    name: 'TableColumn',    props: {      columnHeader: {        type: Object,        required: true      }    }  }</script> <style scoped> </style>

几点重要说明:

(1)表格头部的传参主要分为两类:带children节点和不带children节点的,如下图所示

Element怎么实现动态表格

请注意children节点是为了完成复杂表头的渲染,例如上面这个示例最终的表头渲染样式如下:

Element怎么实现动态表格

那么问题来了,<el-table-column>是<el-table>的标签,那这个<table-column>是个啥?

(2)DynamicTable.vue调用TableColumn.vue组件

Element怎么实现动态表格

DynamicTable.vue通过:column-header给TableColumn.vue传递带children子节点的表头信息,TableColumn.vue接收到这个节点信息后,主要做了以下两件事情:

第一:通过<el-table-column>渲染了一个label标签

第二:继续判断该节点是否存在children子节点

=> 如果存在children节点,继续通过<table-column>进行渲染,继续把这个子节点传给TableColumn.vue组件,重复上述步骤

=> 如果不存在children节点,表示这是一个终止节点,通过<el-table-column>渲染结束

#2# -> 在展示页面使用动态表格组件

<template>  <div class="demo">    <el-card>      <!--查询区域-->      <el-row :gutter="10">        <el-col :span="6">          <div class="grid-content bg-purple">            <span >选择框 -</span>            <el-select              v-model="specified_table"              placeholder="请选择"            >              <el-option                v-for="item in options"                :key="item.zb_code"                :label="item.zb_name"                :value="item.zb_code"              />            </el-select>          </div>        </el-col>        <el-col :span="6">          <div class="grid-content bg-purple">            <el-button type="primary" plain @click="handleQueryClick">查 询</el-button>          </div>        </el-col>      </el-row>      <!--表格区域-->      <dynamic-table        v-if="dynamicTableShow"        :table-data="tableData"        :table-header="tableHeaders"        :height="'550px'"      />    </el-card>  </div></template>
<script>  // 引入组件  import DynamicTable from '@/components/Table/DynamicTable'  // 获取表头信息  import { getTableHeader02_1, getTableHeader02_2, getTableHeader02_3, getTableHeader02_4 } from '@/api/table-header'   export default {    name: 'Index',    components: { // 组件注册      DynamicTable    },    data () {      return {        // -- 查询 ----------------------        options: [          // { zb_name: '指标名', zb_code: '指标代码' }        ],        specified_table: '', // 指标值        // -- 表格 ----------------------        dynamicTableShow: true, // DynamicTable组件重新渲染变量        // 表头数据        tableHeaders: [],        // 表格数据        tableData: []      }    },    created () {      // api-获取指标的下拉框数据      getSpecifiedTable().then(res => {        this.options = res.data      })    },    methods: {      // 判断值是否在数组中      isExistArr (arr, val) {        return arr.includes(val)      },      // 重新渲染表格      refreshTable (zb_code) {        // 根据value值获取label值        const obj = this.options.find((item) => {          return item.zb_code === zb_code        })        console.log(zb_code)        console.log(obj.zb_name)        // 设置dynamicTableShow为false,使得DynamicTable组件重新渲染        this.dynamicTableShow = false        // 根据不同指标渲染不同的表头        const TBArr01 = ['M01', 'M02', 'M03', 'M05'] // 第1类表        const TBArr02 = ['M04', 'M07', 'M08', 'M12'] // 第2类表        const TBArr03 = ['M09', 'M10', 'M11'] // 第3类表        const TBArr04 = ['M06'] // 第4类表        if (this.isExistArr(TBArr01, zb_code)) {          this.tableHeaders = getTableHeader02_1(obj.zb_name) // 渲染表头样式1        }        if (this.isExistArr(TBArr02, zb_code)) {          this.tableHeaders = getTableHeader02_2(obj.zb_name) // 渲染表头样式2        }        if (this.isExistArr(TBArr03, zb_code)) {          this.tableHeaders = getTableHeader02_3(obj.zb_name) // 渲染表头样式3        }        if (this.isExistArr(TBArr04, zb_code)) {          this.tableHeaders = getTableHeader02_4(obj.zb_name) // 渲染表头样式4        }        // api - 获取表格数据        getTableList02(zb_code).then(res => {          this.tableData = res.data        })        // 此处是DOM还没有更新,此处的代码是必须的        this.$nextTick(() => {          // DOM现在更新了          this.dynamicTableShow = true        })      },      // 点击[查询]事件      handleQueryClick () {        const zb_code = this.specified_table        // 校验查询条件不能为空        if (zb_code === '' || zb_code === undefined) {          this.$message.warning('指标不能为空!')        } else {          console.log('zb_code: ' + zb_code)          // 重新渲染表头和表格          this.refreshTable(zb_code)        }      }    }  }</script>

使用动态表格组件相对来说比较简单,唯一需要注意的地方是,渲染表格头部跟数据时必须需要添加以下代码,不然页面无法按照预期完成渲染。

this.$nextTick(() => {    // DOM现在更新了    this.dynamicTableShow = true})

关于this.$nextTick()可以参考官网:https://cn.vuejs.org/v2/guide/reactivity.html

Element怎么实现动态表格

#3# -> 如何给动态表格根据需求动态添加序号列/索引列

在Element UI官方例子中,如果需要给table添加一个序号列或者索引列非常简单,直接在<el-table>里声明一个特殊的<el-table-column>即可。

<el-table-column type="index" width="50"></el-table-column>

那如何在动态表格组件里添加序号列呢?更甚者如果根据需要自行添加或者不添加?

首先我们来改造 DynamicTable.vue

像官方例子一样,我们先在<el-table>里也声明一个<el-table-column>

<el-table-column v-if="isIndex" type="index" width="100" label="序号" align="center" />

注意到这里有一个v-if绑定了一个isIndex值,这个值就是我们需要在父组件进行传值的关键了

在props里声明isIndex为Boolean类型

 props: {      // 表格的数据      tableData: {        type: Array,        required: true      },      // 多级表头的数据      tableHeader: {        type: Array,        required: true      },      // 表格的高度      height: {        type: String,        default: '300'      },      // 是否需要添加序号列      isIndex: {        type: Boolean      }}

在展示页面使用组件时通过:is-index传入指定参数

 <dynamic-table        v-if="dynamicTableShow"        :table-data="tableData"        :table-header="tableHeaders"        :height="'550px'"        :is-index="true"/>

在同页面表头需要切换的情况下,上面这种写法容易在页面初始化时候单独显示一个序号列,就像下面这样,非常不美观

Element怎么实现动态表格

我希望序号列可以和其他普通列一样在表头渲染的时候同时加载,可以这样做

<dynamic-table        v-if="dynamicTableShow"        :table-data="tableData"        :table-header="tableHeaders"        :height="'550px'"        :is-index="isAddIndex"/>

将原本的常量“true”修改成一个变量isAddIndex替代,然后在表头渲染完成的时候将其值修改成true

 this.isAddIndex = true

这样序号列就能跟其他普通列同时进行渲染了。

“Element怎么实现动态表格”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯