最近再做一个大屏项目,需要用到表格滚动效果,之前自己写过js实现,最近发现一个组件vue-seamless-scroll可以实现滚动,感觉挺方便的,准备用一下,但是用完之后才发现这个组件有很多坑需要解决.我把用法和一些问题的解决方法记录一下.
实现表格滚动效果,表格中过长的是文字需要悬停展示,点击每行弹出详情弹框,数据每分钟更新一次.
npm install vue-seamless-scroll --save
import vueSeamlessScroll from 'vue-seamless-scroll'
components: {
vueSeamlessScroll
},
// 监听属性 类似于data概念
computed: {
defaultOption () {
return {
step: 0.2, // 数值越大速度滚动越快
limitMoveNum: 2, // 开始无缝滚动的数据量 this.dataList.length
hoverStop: true, // 是否开启鼠标悬停stop
direction: 1, // 0向下 1向上 2向左 3向右
openWatch: true, // 开启数据实时监控刷新dom
singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
waitTime: 1000 // 单步运动停止的时间(默认值1000ms)
}
}
},
上边的安装使用很简单,大家可以官方文档看看.
刚开始我还觉得这个组件很好用,可是后来现实改变了我的想法.
我把项目代码放上,便于下边问题描述,这是最终代码
{{item.title}}
{{item.caseLevel}}
{{getCaseType(item.caseType)}}
{{formatDate(item.receiveCaseTime)}}
{{item.caseSummary}}
data() {
return {
headerList: [
{ id: 1, title: '级别', className: 'caseLevel', width: 60 },
{ id: 2, title: '类型', className: 'caseType', width: 100 },
{ id: 3, title: '时间', className: 'receiveCaseTime', width: 100 },
{ id: 4, title: '概要', className: 'caseSummary', width: 130 }
],
classOption: {
direction: 1, //滚动方向
step: 0.5, //滚动速度 越打越快
singleHeight: 28, //滚动距离
limitMoveNum: 6
},
}
},
...
clickHang($event) {
if ($event.target.dataset) {
const item = JSON.parse($event.target.dataset.obj)
console.log(item )
//去打开弹框
}
},
handleMouseover(el) {
//判断el是否在content的``标签上
if (el.target.className.includes('table-content')) {
el.target.style.cursor = 'pointer'
//el所在div的transform在y轴上的移动px
let h = parseFloat(
this.$refs['tableCont'].parentElement.parentElement.style.transform
.replaceAll('translate(0px,', '')
.replace('px)', '')
)
//显示div
this.$refs['vc-tooltip'].style.display = ''
this.$refs['vc-tooltip'].innerHTML = el.target.innerHTML
this.$refs['vc-tooltip'].style.left = el.target.offsetLeft - this.$refs['vc-tooltip'].offsetWidth / 2 + 'px'
//判断el所在的div后面是否有元素,有则为第一个div
// if (el.target.parentElement.parentElement.parentElement.nextSibling != null) {
this.$refs['vc-tooltip'].style.top = el.target.offsetTop + h - 10 + 'px'
// } else {
// //当el所在div为第二个即最后一个,弹窗的top还需加上上一个div的高度
// this.$refs['vc-tooltip'].style.top =
// el.target.offsetTop + h + this.$refs['tableCont'].offsetHeight - 10 + 'px'
// }
}
},
handleMouseout(el) {
if (el.target.className.includes('table-content')) {
this.$refs['vc-tooltip'].style.display = 'none'
}
},
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
css
.table_box {
margin: 5px;
text-align: center;
position: relative;
.heared {
display: flex;
height: 21px;
line-height: 21px;
align-items: center;
justify-content: space-between;
background-color: rgba(6, 90, 254, 0.8);
& > div {
margin-left: 5px;
font-family: Noto Sans SC;
font-size: 16px;
font-weight: 700;
color: #fccd1d;
}
}
.scrollBox {
.tooltip-box {
z-index: 5;
background: #303133;
color: #fff;
padding: 10px;
line-height: 1.2;
min-width: 10px;
word-wrap: break-word;
border-radius: 4px;
font-size: 12px;
}
}
.warp {
height: 146px;
overflow: hidden;
// margin: 10px 0;
}
.tableCont {
.hangBox {
height: 27px;
pointer-events: all;
padding-top: 1px;
}
.hang {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 9px;
height: 18px;
line-height: 18px;
font-style: normal;
font-size: 16px;
color: #ffffff;
background-color: rgba(6, 90, 254, 0.5);
font-family: Noto Sans SC;
pointer-events: none;
& > div {
margin-left: 5px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
.table-content {
pointer-events: all;
}
}
.caseLevel {
width: 60px;
}
.receiveCaseTime {
width: 100px;
}
.caseType {
width: 100px;
}
.caseSummary {
width: 130px;
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
1.每一行挂载点击事件
开始的思路是在表格行上添加@click事件就行了,这种方式不可行,发现有的行点击事件挂载不上,后来看了看,明白了大概原因,
由于插件为了实现无缝滚动的效果会把表格html部分复制一份,用于滚动的衔接,但是复制的部分不会挂载点击事件.
解决方法
思路:在每一行中添加属性值, :data-obj=“JSON.stringify(item)”,再通过外层的点击事件clickHang,获取目标元素的属性值.
这里还会引发一个问题的是:
如果每一行中的元素结构比较复杂,:data-obj="JSON.stringify(item)"挂载的位置需要考虑一下,如果挂错地方了,外层点击事件获取不到属性值.
这里我使用css属性把hangBox中hang属性pointer-events: none;然后把hangBox元素设置pointer-events: all;目的就是只留下hangbox的触发事件,内部元素就不会影响了.
2.表格中每一行过长,悬停提示
开始思路是直接用elementui中组件el-tooltip实现,但是又遇到问题了,还是上边的问题,插件把表格html部分复制的部分不会有提示.
解决方法
思路:在外边写个弹框,在组件上挂上,mouseover,mouseout事件,通过鼠标事件控制弹框的显隐,代码在上边大家可以去看看.
这里也遇到了一个问题
由于上边为了解决行点击事件,准确获取每行数据问题,咱们把.hang元素的属性pointer-events: none;导致hang中的元素触发不了悬停,所以得把里边的table-content元素属性设置成pointer-events: all;在这个元素上挂上属性:data-obj=“JSON.stringify(item)”,这样完美解决了.
希望对你有帮助,虽然这个组件使用中出现了好多问题,但是对于只实现滚动的需求,这个组件还是很好用的
-
相关阅读:
Java基础之《netty(6)—NIO快速入门》
【不良事件上报源码】医疗安全(不良)事件管理系统
CentOS7 安装 ElasticSearch7.10
剑指offer 49. 最长不含重复字符的子字符串
游戏开发应该关注质量而不是数量
中国核动力研究设计院使用 DolphinDB 替换 MySQL 实时监控仪表
PLSQL下载并安装
SpringBoot启动的时候做了什么(1)
LaTeX 010:让 texify 支持 Biber
内存池的实现4 alloc内存池
-
原文地址:https://blog.csdn.net/weixin_46995731/article/details/133375813