vue-iview table时间表格显示(行合并、背景颜色显示)

近日需要做一个时间表,在使用iview后,发现iview中的table能实现良好的效果,遂尝试了下。需要View UI (iView)4.0.0 以上版本。

最终效果图

请求后台,获取左侧固定时间值,上方columns动态值

 1.时间表columns为动态数据,后台获取数据,动态生成columns字段

getColumn () {
                var list = this.columns

                this.Coach_List.forEach(item => {
                    list.push({
                        title: item.name,
                        key: item.id,
                        align: 'center',
                        minWidth: 80,
                        render: (h, params) => {
                            if (params.row[item.RowId] != null) {
                                return h('div', { class: 'red' }, params.row[item.id].MemberName)
                            }
                        }
                    })
                })
                this.columns = list;
                // 调取数据处理方法
                this.getDataDispose()
            },

2.将后台返回的数据按照columns重新生成

/*
            *getDataDispose 数据处理
            * 将数据按教练RowId栏位增加
            * */
            getDataDispose () {
                let that = this
                // 表格数据循环
                this.table_list.forEach(item => {
                    // 教练循环
                    that.Coach_List.forEach(coach => {
                        // 记录循环
                        that.TeachRetai.forEach(retai => {
                            // 判断是否属于这个教练
                            if (coach.RowId === retai.CoachId) {
                                // 时间处理
                                var time = Number(item.timeName.substring(0, 2)) * 4 + Number(item.timeName.substring(3, 5)) / 15
                                var startTime = Number(retai.StaTime.toString().substring(0, 2)) * 4 + Number(retai.StaTime.toString().substring(3, 5)) / 15
                                var endTime = Number(retai.EndTime.toString().substring(0, 2)) * 4 + Number(retai.EndTime.toString().substring(3, 5)) / 15
                                // 比较时间
                                if (time >= startTime && endTime >= time) {
                                    item[coach.RowId] = {
                                        MemberName: retai.MemberName,
                                        id: retai.id,
                                        className: 'red'
                                    }
                                }
                            }
                        })
                    })
                })
                // 调用样式设置方法
                this.setRowClass()
                // 调用计算单元格合并多少行方法
                this.assembleData(this.table_list)
            },

3.调用样式设置方法,通过columns中的函数,返回带有clasa的div,设置不同的css

            /*
            *setRowClass 样式处理
            *根据td下的div数量,判断是否有数据 根据样式名称,手动设置css
            * */
            setRowClass () {
                if (this.$refs.table.$el) {
                    setTimeout(() => {
                        // 表格加载结束后加载dom,需延迟一下
                        let td = document.querySelectorAll(`td`)
                        for (let i = 0; i < td.length; i++) {
                            // 操作dom,这边需要另外一些判断,比如当前className以及样式,这样好处是减少操作dom次数
                            // 坏处是className判断比较不好判断,以及cssText样式比较难获取
                            let div = td[i].getElementsByTagName('div')
                            if (div.length > 1) {
                                //可以拿到div下的clasname,自行设置css
                                td[i].style.cssText = 'color: white; background:red;font-weight:600'
                            }
                        }
                    }, 20)
                }
            },

4.计算单元格合并多少行,指定某个栏位重复的合并

            /**
             * assembleData 计算合并单元格数量
             * */
            assembleData (data) {
                let names = []
                // 筛选出不重复的指定栏位,将其放到 names数组中
                data.forEach(e => {
                    this.Coach_List.forEach(coach => {
                        if (e[coach.RowId] != null) {
                            if (!names.includes(e[coach.RowId].RetaiId)) {
                                names.push(e[coach.RowId].RetaiId)
                            }
                        }
                    })
                })
                let nameNums = []
                // 将names数组中的 name值设置默认合并0个单元格,放到 nameNums中
                names.forEach(e => {
                    nameNums.push({ name: e, num: 0 })
                })
                // 计算每种 name值所在行需要合并的单元格数
                data.forEach(e => {
                    this.Coach_List.forEach(coach => {
                        nameNums.forEach(n => {
                            if (e[coach.RowId] != null) {
                                if (e[coach.RowId].RetaiId === n.name) {
                                    n.num++
                                }
                            }
                        })
                    })
                })

                // 将计算后的合并单元格数整合到 data中
                data.forEach(e => {
                    this.Coach_List.forEach(coach => {
                        nameNums.forEach(n => {
                            if (e[coach.RowId] != null) {
                                if (e[coach.RowId].RetaiId === n.name) {
                                    if (names.includes(e[coach.RowId].RetaiId)) {
                                        e[coach.RowId]['mergeCol'] = n.num
                                        // 删除已经设置过的值(防止被合并的单元格进到这个 if 语句中)
                                        names.splice(names.indexOf(n.name), 1)
                                    } else {
                                        // 被合并的单元格设置为 0
                                        e[coach.RowId]['mergeCol'] = 0
                                    }
                                }
                            }
                        })
                    })
                })

                // 将整理后的数据交给表格渲染
                this.table_list = data
            }

table代码,通过:spanmethod调用 handleSpan方法,将单元格合并

<Table class="ivu-mt"
                   ref="table"
                   :loading="loading"
                   :columns="columns"
                   :height="tableHeight"
                   :data="table_list"
                   :span-method="handleSpan"
                   disabled-hover
                   border>
  </Table>
            /**
             * handleSpan 渲染回调
             * 根据单元格key值,哪去row[key]的值,获取当前单元格应合并行数
             * */
            handleSpan ({ row, column, rowIndex, columnIndex }) {
                if (row[column.key] != null) {
                    let x = row[column.key].mergeCol === 0 ? 0 : row[column.key].mergeCol
                    let y = row[column.key].mergeCol === 0 ? 0 : 1
                    return [x, y]
                } else return [0, 0]
            },

其实最初是想通过iview的滚动实现此功能,但没想到iview的scroll没有监听的方法,便换了个思路使用了table,整体效果不错。

参考链接 (34条消息) View UI (iview)表格 行/列合并 教程_悟世君子的博客-CSDN博客_iview table 合并列https://blog.csdn.net/wsjzzcbq/article/details/106079081

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值