Element实现动态表格的示例代码

目录
  • 【代码背景】
  • 【代码实现】
    • #1# -> 代码复用的基础是你需要一个可复用的组件
    • #2# -> 在展示页面使用动态表格组件
    • #3# -> 如何给动态表格根据需求动态添加序号列/索引列

【代码背景】

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

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

<el-table :data="tableData" style="width: 100%">
    <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节点的,如下图所示

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

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

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

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 style="margin-right: 10px">选择框 -</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

#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"
/>

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

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

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

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

 this.isAddIndex = true

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

【参考资料】

https://www.jianshu.com/p/9c4ba833658f

https://www.cnblogs.com/llcdxh/p/9473458.html

到此这篇关于Element实现动态表格的示例代码的文章就介绍到这了,更多相关Element 动态表格内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • element ui 表格动态列显示空白bug 修复方法

    在使用element ui框架进行项目开发的时候,表格的列是根据后台数据动态生成的,但是发现在列刷新的视乎,会出现表格完全空白,没有显示的情况,经过自己编写demo发现,在增加列的情况下表格正常,但是一旦表格列减少时就会出问题,对element底层代码进行调试发现,在node_modules/element-ui/lib/elementui.common.js 中的一个函数. removeColumn: function removeColumn(states, column) { var _c

  • elementUI table表格动态合并的示例代码

    1.最近在做的erp项目,有一个需求是同一个客户下的同种订单,需要合并展示.使用elementUI table组件的方法 :span-method="objectSpanMethod".官网上看了一下demo,做的很直白,不过不太符合业务.在网上找了篇文章参考了一下 2.效果图如下: 在动态处理从后端拿回来的数据的时候,是需要从数据中找到一个唯一的"标识"去判断是否是相同种类的数据.然后根据这个"标识"去做逻辑判断. 3.代码: //合并单元格

  • element 动态合并表格的步骤

    前言 element 官方的例子太简单了,不满足实际的需求 数据肯定是动态的,合并的行数,列数都是动态的,该如何知道每一行的合并数呢 需求 动态合并表格,数据来源于数据库 正文 一开始,我的数据源是单独的数组,表格数据合并了几个数据, 我根据各个数组的长度,来决定每一行的合并数 结果:有些数据是正常的,但有些又合并出错了.计算的方式不对 尝试二 dataPretreatment() 用这个方法 计算出每一行的行数 dataPretreatment(){ //表格数据列合并预处理,生成一个与行数相

  • vue+element创建动态的form表单.以及动态生成表格的行和列

    动态创建form表单,网上有插件 (form-create) 不过我不知道它怎么用,没有使用成功,如果你使用成功了,欢迎下方留言. 最后我使用了笨方法,针对各个表单写好通用的组件,然后根据type用v-if来渲染对应的表单,数据,事件什么的都可以动态的传进去,比较好用 复制代码  1 <el-form size="mini" class="lj-form lj-form-s1">  2             <div v-for="(i

  • vue+element table表格实现动态列筛选的示例代码

    需求:在用列表展示数据时,出现了很多项信息需要展示导致表格横向特别长,展示就不够明晰,用户使用起来可能会觉得抓不住自己的重点. 设想实现:用户手动选择表格的列隐藏还是展示,并且记录用户选择的状态,在下次进入该时仍保留选择的状态. 效果图如下: 原: 不需要的关掉默认的勾选: 实现代码: HTML部分就是用一个多选框组件展示列选项 用v-if="colData[i].istrue"控制显示隐藏,把列选项传到checkbox里再绑定勾选事件. <el-popover placemen

  • 详解Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)

    动态表单生成 ElementUI官网引导 Element表单生成 Element动态增减表单,在线代码 关键配置 template中,form和form-item的写法和绑定 data里的值为空 methods中,向后台获取数据的函数写法  1. form,form-item,input的写法[^code] <el-form :model="dynamicValidateForm" label-width="120px" ref="dynamicVa

  • VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解

    先看看ElementUI里关于el-table的template数据结构: <template> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-tabl

  • Element实现动态表格的示例代码

    目录 [代码背景] [代码实现] #1# -> 代码复用的基础是你需要一个可复用的组件 #2# -> 在展示页面使用动态表格组件 #3# -> 如何给动态表格根据需求动态添加序号列/索引列 [代码背景] 有这样一个业务需求场景,有大概十几张表归属于某个类别,用户希望在同一个页面,通过选择不同的查询指标展示不同的表格,这些表的表头样式类似但是又不完全相同,怎么做呢? 到目前为止所有基于Element UI的表格样式都是直接在页面写死的,像官方这样: <el-table :data=&

  • 史上最简单的MyBatis动态SQL入门示例代码

    假如有如下的关于书籍基本信息的表: DROP DATABASE IF EXISTS `books`; CREATE DATABASE `books`; USE books; DROP TABLE IF EXISTS `book`; CREATE TABLE `book` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(128) DEFAULT NULL, `author` varchar(64) DEFAULT NULL, `pres

  • Python实现Word表格转成Excel表格的示例代码

    准备工作 pip install docx pip install openpyxl 具体代码 # 没有的先pip install 包名称 from docx import Document from openpyxl import Workbook document = Document('Docx文件路径.dicx') count = 0 tables = [] wb = Workbook() ws = wb.active # 设置列数,可以指定列名称,有几列就设置几个, # A对应列1,B

  • jQuery 动态粒子效果示例代码

    1.js部分 var RENDERER = { PARTICLE_COUNT : 1000, PARTICLE_RADIUS : 1, MAX_ROTATION_ANGLE : Math.PI / 60, TRANSLATION_COUNT : 500, init : function(strategy){ this.setParameters(strategy); this.createParticles(); this.setupFigure(); this.reconstructMetho

  • SpringBoot读取excel表格的示例代码

    SpringBoot读取excel表格 共同探讨,向各位大佬学习 走向CEO,迎娶白富美 pom.xml依赖 <!--springboot核心依赖--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</vers

  • Django与AJAX实现网页动态数据显示的示例代码

    前言 这部分已经折腾我两天了,还是没有头绪,可能还会折腾更久,最后在第三天上午解决问题,在一个不起眼的地方被坑了,jQuery加载的问题.会者不难,难者不会,希望后面人少走弯路吧 环境 windows10 pycharm2017.3.3 professional edition python3.6.4 django2.0.2 方法 创建后台读取数据函数,用于后台从数据库读取数据.在views.py文件内增加以下代码 from django.http import JsonResponse def

  • Android动态表格的实现代码(内容、样式可扩缩)

    1.实现动态表格效果如下: 2.项目如下: **3.activity_smart_table.xml,表格布局代码如下:** <com.bin.david.form.core.SmartTable android:id="@+id/table" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="0dp"

  • python通过pillow识别动态验证码的示例代码

    目录 环境配置  安装 pillow(PIL)库 识别过程 生活中,我们在登录微博,邮箱的时候,常常会碰到验证码.在工作时,如果想要爬取一些数据,也会碰到验证码的阻碍.本次试验将带领大家认识验证码的一些特性,并利用 Python 中的 pillow 库完成对验证码的破解. 环境配置 Python 2.7 Pillow 模块 有个问题就是python2.7目前只能让使用到2020年,现在再利用2.7下载好多东西都会报错,也该是时候更新到python3.7了,本文还是依赖于2.7的环境. 识别验证码

  • Mybatis动态SQL的示例代码

    目录 基本流程 IF,Where Set Choose(when,otherwise) SQL片段 总结 什么是动态SQL:动态SQL就是根据不同的条件生成不同的SQL语句 基本流程 1,数据库准备一张表 2,导包 3,编写核心配置文件 4,编写实体类 5,编写实体类对应的Mapper和Mapper.xml文件 6,在核心配置文件中注册Mapper.xml 7,测试 开启自动驼峰命名规则映射 <!--开启驼峰命名映射--> <setting name="mapUnderscor

  • Flutter实现笑嘻嘻的动态表情的示例代码

    目录 前言 AnimatedContainer 介绍 组件结构 细节实现 总结 前言 身在孤岛有很多无奈,比如说程序员属于比较偏门的职业.尤其是早些年,在行业里跳过几次槽后,可能你就已经认识整个圈子的人了.然后,再跳槽很可能就再次“偶遇”前同事了,用大潘的口头语来说就是:“好尴尬呀”.因此, 问起职业,往往只能是回答是搞计算机的.结果可能更尴尬,问的人可能笑嘻嘻地瞅着你,像看怪物一样看着你,接着突然冒出一句灵魂拷问:“我家电脑坏了,你能修不?”不过也不奇怪,那个时候在岛上重装一个 Windows

随机推荐