vue+element实现动态表格(table)动态表头与表单内容展示

前言描述:
       接到这么一个需求,经分析后我认为需要对某数据做一个动态的展示,每一个分页中展示的数据应为对应分页接口返回的最大数词条数展示,比如当前页为1,且在一页数据最多10条时,如果返回的数据中当前所有词条最多可以有3个,那么表头最多就是命名为词条3;
       当分页进入到第2页,返回的数据中,发现最多的一组数据中词条数据达到了6个,那么当前表头应该展示词条6;
       以此类推,每次接口请求后的表头都是动态展示的,下图为动态表头图片展示。


1、template标签区域代码示例:
<template>
  <div>
    <div class="card_entry_table">
      <el-table
        size="mini"
        :header-cell-style="{ background: '#e5e5e5' }"
        :row-style="{ height: '60px' }"
        :data="tableData"
        :max-height="tableMaxHeight"
      >
        <!-- 动静结合表头 -->
          <el-table-column
          v-for="(item, index) in tableColumnList"
          :key="index"
          :prop="item.prop"
          :label="item.label"
          :align="item.align ? item.align : 'left'"
          :min-width="item.min_width"
        >
          <template #default="scope">
            {{ scope.row[item.prop] || '--' }}
          </template>
        </el-table-column>
        <!-- aiction操作栏区域 此处代码省略-->
        </el-table>
    </div>
  </div>
<template>
2、script标签区域代码示例:
export default {
  data() {
      return{
            tableMaxHeight: 'auto',
            tableData: [], // 表单数据
            maxLength: 0, //用于保存动态表头最大数组长度
            // 静态列表展示表头
            staticTableColumnList:[ 
            {
               prop: 'search_keyword',
               label: 'card对应搜索关键词',
               min_width: '200'
            },
            {
               prop: 'business_name',
               label: '业务名称',
               min_width: '200'
            },
            {
               prop: 'business_summary',
               label: '业务摘要',
               min_width: '200'
            },
            {
               prop: 'business_wiki_url',
               label: '业务百科',
               min_width: '200'
        }
      ],
           syncTableColumnList: [],// 接口动态表头

           //最终使用表头(动静结合)默认是无数据的时候展示的表头名字,我是设置的这个,也可以吧静态表头设置成这个,看自己的业务要求
           tableColumnList: [
            {
               prop: 'loadingText',
               label: 'XXX配置表单',
               width: '',
               align: 'center'
        }
      ],
      
      }
  },

  methods:{
           //获取当前百科card表单数据
           async getTableList() {
           //每次接口请求时均需重置最多条数数据
           this.maxLength = 0
           try {
        const { message, code, data, total } = await post('/api_pc/AI/search_cards', {
          data: this.query
        })
        if (code == '000000' && data) {
          if (Array.isArray(data) && data.length == 0) {
            this.tableData = []
            return false
          }
             //动态处理表头,遍历需要看一下最长的词条(词条对应知识的长度是多少,我们要保存最大值,创建对应的动态表头)
            data.forEach(item => {
            const { config_list, ...rest } = { ...item }
            if (Array.isArray(config_list)) {
              const length = config_list.length
              if (length > this.maxLength) {
                this.maxLength = length
              }
            }
          })
         
           if (this.maxLength) {
            //每次接口请求时均需重置动态表头数据
            this.syncTableColumnList = []
            for (let i = 1; i <= this.maxLength; i++) {
              this.syncTableColumnList.push({
                prop: `name${i}`,
                label: `词条${i}`,
                min_width: '100'
              })
               this.syncTableColumnList.push({
                prop: `path${i}`,
                label: `词条${i}对应知识`,
                min_width: '200'
              })
            }
          }
             this.tableColumnList = 
             this.staticTableColumnList.concat(this.syncTableColumnList)
             
          //先置空表单数据
          this.tableData = []
          //处理接口返回的表单词条数据,用来展示列表表单内容数据
            this.tableData = data.map(item => {
            let newObj = JSON.parse(JSON.stringify(item))
            if (Array.isArray(item.config_list) && item.config_list.length > 0) {
              item.config_list.forEach((config, index) => {
                newObj[`name${index + 1}`] = config.name
                newObj[`path${index + 1}`] = config.path
              })
            }
            return newObj
          })
           this.total = total || 0

          this.$nextTick(() => {
            scrollTop(document.querySelector('.card_entry_table'))
          })
        } else {
          throw message
        }
         } catch (err) {
        this.$message.error(`${err}`)
      }
    },
  }

补充:
      这里可以发现表头是动态的,表单数据返回的词条和词条对应知识字段也是数量不固定的,那么根据表格常见的crud,必然是有前端操作新增的,且新增是动态的,可以设置最大限制新增数量,可以新增就可以删除新增,下方是我在处理新增(编辑)表单时对于词条相关的处理。

3、动态新增词条N(词条对应知识N)代码示例:
 

 //增减操作 configList描述数组 @click="actionMsgItems('add或者delete', item.id)"
由于后端没有存id字段,删除时需要id标识,在初始化的时候可以把索引当做id,编辑或者新增时可选时间戳作为唯一标识
    actionMsgItems(key, id) {
      switch (key) {
        case 'add':
          let index = this.encyclopediaCardForm.config_list.findIndex(item => item.id === id)
          if (index != -1) {
            this.encyclopediaCardForm.config_list.splice(index + 1, 0, {
              name: '',//这个字段就是词条
              path: '',//这个字段就是词条对应知识
              id: Date.now()
            })
             } else {
            this.$message.error('ID查询失败,无法添加!')
          }
          break
        case 'delete':
             this.encyclopediaCardForm.config_list = 
             this.encyclopediaCardForm.config_list.filter(
            item => item.id != id
          )
          break
        default:
          break
      }
    },


 

Vue.js框架中结合Element UI库实现表格的新增、编辑和删除功能通常涉及以下几个步骤: 1. **数据绑定**:首先,你需要创建一个数组来存储表格的数据,并在Vue组件的data选项中定义。当有新增、编辑或删除操作时,这个数组需要实时更新。 ```javascript data() { return { tableData: [], // 初始化空数组 }; } ``` 2. **表格渲染**:使用Element UI的`el-table`组件展示数据,通过`v-for`指令遍历数组,将每个数据项作为tableData的一个元素。 3. **新增操作**:可以添加一个按钮,点击后弹出模态框,用户输入信息并提交时,向`tableData`数组追加新的对象。 4. **编辑操作**:在表格中设置编辑列,当用户双击某一行或者点击编辑按钮,进入编辑模式,允许修改数据,然后保存时更新对应的表格行。 5. **删除操作**:在每一行的末尾提供删除按钮,点击后从数组中移除该行对应的对象。 6. **事件处理**:对于以上操作,都需要配合Vue的响应式特性,监听用户的交互事件(如click、dblclick等),并触发相应的数据变更方法(例如`push`, `set`, 或者`splice`)。 以下是简化版的示例代码片段: ```html <template> <el-table :data="tableData"> <!-- 添加、编辑和删除操作列 --> <el-table-column type="action" width="180"> <template slot-scope="scope"> <el-button @click="editRow(scope.$index)" :disabled="scope.row.disabled">编辑</el-button> <el-button @click="deleteRow(scope.$index)">删除</el-button> </template> </el-table-column> <!-- 表头和内容列 --> <el-table-column prop="name" label="Name"></el-table-column> <!-- 其他列... --> </el-table> <!-- 新增模态 --> <el-dialog v-model="dialogVisible" title="新增"> <el-form ref="addForm" :model="formAdd" rules="..."> <!-- 新增表单... --> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="handleAdd">保存</el-button> </div> </el-dialog> </template> <script> export default { data() { return { dialogVisible: false, formAdd: {}, // 新增表单数据 tableData: [], }; }, methods: { editRow(index) { // 编辑操作... }, deleteRow(index) { this.tableData.splice(index, 1); }, handleAdd() { this.dialogVisible = false; this.tableData.push(this.formAdd); // 添加到数据数组 } } }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值