iview Table表格组件无法拆分单元格的解决思路

Posted jlfw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iview Table表格组件无法拆分单元格的解决思路相关的知识,希望对你有一定的参考价值。

最近在开发的Vue项目中,使用了iview第三方UI库;对于表格组件的需求是最多的,但是在一些特定场景下,发现iview的表格组件没有单元格合并与拆分的API,搜了一下发现很多同学提问关于iview表格组件的单元格如何拆分和合并的问题。因此某家在此说下我们在项目中如何填的这个坑。
因为我们项目中首要的是单元格拆分的,因此以拆分为例。基本思路就是:不在源码层面进行修改;在外部对Table组件进行二次封装。使用vue render函数对表格组件的表格列配置数据进行动态改造,普通单元格渲染span标签呈现数据,要拆分的单元格渲染原生table标签;最后隐藏嵌套表格的边框及调整相关原生表格样式。
这里注意之前打算用iview Table组件进行嵌套,但是发现修改table组件的样式非常麻烦,而且没有效果,一不小心就容易污染全局样式,因此后来用原生table标签完美解决样式不可控问题。

1. 首先对于整体表格的列配置数据中有拆分的列进行添加split为true的属性。
技术图片

2.对于表格数据源进行子表格数据定义,也就是用数组的形式包含子表格数据

技术图片

3.使用vue render函数动态渲染改造表格列结构,通单元格渲染span标签呈现数据,要拆分的单元格渲染原生table标签。

      let vm = this;
      this.columnsList.forEach(item => {
        // 可编辑单元格
        if (item.editable) {
          item.render = (h, param) => {
            let currentRow = this.thisTableData[param.index];
            if (currentRow.editting) {
              // 正在编辑
              if(item.split){
                    var childArray = currentRow[item.key];
                    var inputArray=[];
                    childArray.forEach(item => {
                          var aa = h(‘Input‘, {
                                      style:{
                                          width:‘80%‘,
                                          ‘margin-top‘:‘10px‘,
                                          ‘margin-bottom‘:‘10px‘
                                       },
                                      props: {
                                          type: ‘text‘,
                                          value: item.child
                                       },
                                      on: {
                                            ‘on-change‘ (event) {
                                                  let key = param.column.key;
                                                  var ddd = vm.edittingStore[param.index][key];
                                                  //item.child = event.target.value;
                                                  //计算当前的索引
                                                  var currentIndex = childArray.indexOf(item);
                                                  //更新数据
                                                  vm.edittingStore[param.index][key][currentIndex].child = event.target.value;
                                             }
                                       }
                           });
                          inputArray.push(aa)

                          var currentIndex = childArray.indexOf(item);
                          if(currentIndex!==childArray.length-1){
                                var bb = h(‘hr‘,{
                                            style:{
                                                height:‘1px‘,
                                                ‘background-color‘:‘#e9eaec‘,
                                                border:‘none‘
                                             }
                                 })
                                inputArray.push(bb)
                           }
                     })
                    return h(‘Row‘,inputArray)
               }
              else
              {          
                    return h(‘Input‘, {
                                style:{
                                    width:‘80%‘
                                },
                                props: {
                                    type: ‘text‘,
                                    value: currentRow[item.key]
                                },
                                on: {
                                    ‘on-change‘ (event) {
                                        let key = param.column.key;
                                        vm.edittingStore[param.index][key] = event.target.value;
                                    }
                                }
                     });
               }
            } else {
              // 没在编辑
              if (this.editIncell) {
                // 单元格内编辑
                return h(‘Row‘, {
                  props: {
                    type: ‘flex‘,
                    align: ‘middle‘,
                    justify: ‘center‘
                  }
                }, [
                  h(‘Col‘, {
                    props: {
                      span: ‘16‘
                    }
                  }, [
                    currentRow.edittingCell[param.column.key] ? cellInput(this, h, param, item) : h(‘span‘, currentRow[item.key])
                  ]),
                  h(‘Col‘, {
                    props: {
                      span: ‘8‘
                    }
                  }, [
                    currentRow.edittingCell[param.column.key] ? saveIncellEditBtn(this, h, param) : inCellEditBtn(this, h, param)
                  ])
                ]);
              } else {
                // 非单元格内编辑
                  if(item.split){

                        if(currentRow.childProject.length==1){
                            var value = currentRow.childProject[0].child;
                            return h(‘span‘, value);
                        }

                        //用原生html标签渲染
                        var trAarry=[];
                        var childArray = currentRow[item.key];
                        childArray.forEach(item => {
                              var aa = h(‘tr‘,{},[
                                        h(‘td‘,{
                                            style:{
                                                border:0,
                                                ‘text-align‘:‘center‘
                                            }
                                        },item.child),
                              ])
                              trAarry.push(aa)
                                    
                              var currentIndex = childArray.indexOf(item);
                              if(currentIndex!==childArray.length-1){
                                    var bb = h(‘hr‘,{
                                            style:{
                                                height:‘1px‘,
                                                ‘background-color‘:‘#e9eaec‘,
                                                border:‘none‘
                                             }
                                    })
                                    trAarry.push(bb)
                              }
                        })

                        return h(‘table‘,{style:{
                                  ‘width‘:‘100%‘,
                                  margin:0,
                                  border:0
                        }},trAarry)
                  }
                  else  return h(‘span‘, currentRow[item.key]);
              }
            }
          };
        }
        // 编辑和删除按钮
        if (item.handle) {
          item.render = (h, param) => {
            let currentRowData = this.thisTableData[param.index];
            let children = [];
            item.handle.forEach(item => {
              if (item === ‘edit‘) {
                children.push(editButton(this, h, currentRowData, param.index));
              } else if (item === ‘delete‘) {
                children.push(deleteButton(this, h, currentRowData, param.index));
              }
            });
            return h(‘div‘, children);
          };
        }
      });
    } 

4.完美实现了单元格拆分为列的效果。
技术图片

以上是关于iview Table表格组件无法拆分单元格的解决思路的主要内容,如果未能解决你的问题,请参考以下文章

使用vue自定义指令合并iview表格单元格

iview Table组件使用过滤器时无法加载表头解决办法

iView中表格(Table)添加点击行展开扩展说明的功能

iView中表格(Table)添加点击行,展开扩展,默认展开所有行

vuejs或者iview当中表格怎么合并单元格

如何将EXCEL表格里一个单元格的数据拆分为两列