近日需要做一个时间表,在使用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方法,将单元格合并
/**
* 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