Vue 之 vue-seamless-scroll 实现简单自动无缝滚动,且添加对应点击事件的简单整理
Vue 之 vue-seamless-scroll 实现简单自动无缝滚动,且添加对应点击事件的简单整理
目录
一、简单介绍
Vue 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。
本节介绍,vue 中添加 vue-seamless-scroll,简单实现自动无缝滚动的效果,并对应添加点击事件 ,如果有不足之处,欢迎指出,或者你有更好的方法,欢迎留言。
vue-seamless-scroll 是一个基于Vue.js的简单无缝滚动组件, 基于requestAnimationFrame实现,配置多满足多样需求。目前支持上下左右无缝滚动,单步滚动,以及支持水平方向的手动切换功能。
vue-seamless-scroll 配置项:
key | description | default | val |
---|---|---|---|
step |
数值越大速度滚动越快 | 1 |
Number |
limitMoveNum |
开启无缝滚动的数据量 | 5 |
Number |
hoverStop |
是否启用鼠标hover控制 | true |
Boolean |
direction |
方向 0 往下 1 往上 2向左 3向右 | 1 |
Number |
openTouch |
移动端开启touch滑动 | true |
Boolean |
singleHeight |
单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1 | 0 |
Number |
singleWidth |
单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3 | 0 |
Number |
waitTime |
单步停止等待时间(默认值1000ms) | 1000 |
Number |
switchOffset |
左右切换按钮距离左右边界的边距(px) | 30 |
Number |
autoPlay |
1.1.17版本前手动切换时候需要置为false | true |
Boolean |
switchSingleStep |
手动单步切换step值(px) | 134 |
Number |
switchDelay |
单步切换的动画时间(ms) | 400 |
Number |
switchDisabledClass |
不可以点击状态的switch按钮父元素的类名 | disabled |
String |
isSingleRemUnit |
singleHeight and singleWidth是否开启rem度量 | false |
Boolean |
navigation |
左右方向的滚动是否显示控制器按钮,true的时候autoPlay自动变为false | false |
Boolean |
vue-seamless-scroll 回调事件:
name | description | calback params |
---|---|---|
ScrollEnd |
一次滚动完成的回调事件 | null |
操作环境:
- win 10
- node v14.20.0
- npm 8.5.3
- @vue/cli 5.0.6
- vue 2.6.14
- vue-seamless-scroll 1.1.23
二、安装和使用
1、npm
npm install vue-seamless-scroll --save
2、yarn
yarn add vue-seamless-scroll
3、cdn
https://cdn.jsdelivr.net/npm/vue-seamless-scroll@latest/dist/vue-seamless-scroll.min.js
4、使用
// 全局注册
import Vue from 'vue'
import scroll from 'vue-seamless-scroll'
Vue.use(scroll)
//或者
//Vue.use(scroll,{componentName: 'scroll-seamless'})
// 局部注册
import vueSeamless from 'vue-seamless-scroll'
export default {
components: {
vueSeamless
}
}
// 使用
<div id="app">
<vue-seamless-scroll></vue-seamless-scroll>
</div>
三、效果图
自动无缝滚动,且点击对应的每条都会显示点中的索引,和显示标题,如图
四、vue-seamless-scroll 点击事件实现原理
1、在 vue-seamless-scroll 包一层 div ,然后添加对应点击事件获取 $event
<div @click="handleButton($event)">
2、添加 tr 每组数据 class 和 id 标记
<tr v-for='(item, i) in listData' :key='i' class='labelIndex' :id='i'>
3、点击事件处理 event ,得到点击标记的 class,最终获得点击 id
// 处理鼠标点击到哪条,可添加跳转
handleButton(e) {
// let InfoAnync = JSON.parse(e.target.dataset.obj)
// console.log(InfoAnync,' =====> InfoAnync')
console.log(e, ' =====> e')
console.log(e.path, ' =====> e.path')
let length = e.path.length
let labelIndex = -1
for(let i=0;i < length; i++){
if(e.path[i].className === 'labelIndex'){
labelIndex = i;
break
}
}
if(labelIndex !== -1){
console.log(e.path[labelIndex].innerText, ' =====> e.path[labelIndex].innerText')
alert('labelIndex.id = ' + e.path[labelIndex].id + ',title: ' + this.listData[e.path[labelIndex].id].title)
}else{
alert('未找到数据,请检查')
}
}
五、简单实现
1、首先创建一个 vue 文件,添加标题和标题栏
2、引入 vue-seamless-scroll ,使用并且传递数据,然后 v-for 添加显示数据
3、在 vue-seamless-scroll 中,添加点击事件,首先外包一个 div,添加一个点击事件
4、接着,给 tr 添加 class 和 id ,到时点击事件会根据此 class 和 id 进行对应的判断
5、点击事件处理,通过对应 e.path[i].className 获取之前标记的 class,然后在获取到对应绑定的 id 值,最后即可通过数据列表获取到,对应的信息,即可对应进行相关点击事件的处理了
6、vue-seamless-scroll 简单optionSetting设置如下
7、vue-seamless-scroll 简单数据展示如下
8、运行显示,浏览器效果如图
六、关键代码
<template>
<div class="wrap-container sn-container">
<div class="sn-content">
<div class="sn-title">消息自动滚动播放</div>
<div class="sn-body">
<div class="wrap-container">
<div class="table">
<table border="0" cellpadding='0' cellspacing='0' class="table-header">
<tbody>
<tr>
<td width='60%'>
<span>标 题</span>
</td>
<td width='20%'>
<span>日 期</span>
</td>
<td width='20%'>
<span>热 度</span>
</td>
</tr>
</tbody>
</table>
<div @click="handleButton($event)">
<vue-seamless-scroll :data='listData' class="seamless-warp" :class-option="optionSetting">
<table border='0' cellpadding='0' cellspacing='0' class='item'>
<tbody>
<tr v-for='(item, i) in listData' :key='i' class='labelIndex' :id='i'>
<td width='100%' class="title">
<span>{{item.title}}</span>
</td>
<td width='20%'>
<span>{{item.date}}</span>
</td>
<td width='20%'>
// 显示热度,且根据不同数值,显示不同颜色
<span
:class="{colorRed: item.hot > 2555,colorOrange: item.hot < 10}"
>{{item.hot}}</span>
</td>
</tr>
</tbody>
</table>
</vue-seamless-scroll>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import vueSeamlessScroll from 'vue-seamless-scroll'
export default {
name: 'seamless-scroll',
components: {
vueSeamlessScroll
},
data() {
return {
// 数据
listData: [{
title: '钱花哪了?一图带你读懂年轻人的消费观',
date: '2020-05-05',
hot: 2306
}, {
title: '“五一”假期前三天国内旅游收入超350亿元',
date: '2020-05-02',
hot: 5689
}, {
title: '滴滴、美团、哈啰交战,本地生活会是终局?',
date: '2020-05-02',
hot: 9
}, {
title: '“互联网+文化”逆势上行文娱消费云端真精彩',
date: '2020-04-25',
hot: 288
}, {
title: '乐观还是悲观?巴菲特是个现实主义者!',
date: '2020-04-21',
hot: 158
}, {
title: 'B站的后浪,会把爱优腾拍在沙滩上吗?',
date: '2020-04-20',
hot: 889
}, {
title: '华为如何做投资的:先给两亿订单一年上市',
date: '2020-04-01',
hot: 5800
}, {
title: '马斯克:特斯拉股价太高了,我要卖豪宅',
date: '2020-03-25',
hot: 6
}, {
title: '人民日报海外版:云模式巧解“就业难”',
date: '2020-03-16',
hot: 88
}, {
title: '刚刚港股"崩了":狂跌近1000点!',
date: '2020-03-12',
hot: 88
}, {
title: '个人健康信息码国家标准发布',
date: '2020-02-28',
hot: 5
}, {
title: '传软银国际裁员约10%两名管理合伙人离职',
date: '2020-02-15',
hot: 258
}, {
title: '27万个岗位:区块链、人工智能等专场招聘',
date: '2020-02-10',
hot: 198
}, {
title: '一季度电商发展势头迅猛农村电商破1300万家',
date: '2020-02-08',
hot: 19
}]
}
},
computed:{
optionSetting(){
return{
step: 0.5, // 数值越大速度滚动越快
limitMoveNum: 2, // 开始无缝滚动的数据量 this.dataList.length
hoverStop: true, // 是否开启鼠标悬停stop
direction: 1, // 0向下 1向上 2向左 3向右
autoPlay: true, // 是否自动滚动
openWatch: true, // 开启数据实时监控刷新dom
singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
waitTime: 1000 // 单步运动停止的时间(默认值1000ms)
}
}
},
methods:{
// 处理鼠标点击到哪条,可添加跳转
handleButton(e) {
// let InfoAnync = JSON.parse(e.target.dataset.obj)
// console.log(InfoAnync,' =====> InfoAnync')
console.log(e, ' =====> e')
console.log(e.path, ' =====> e.path')
let length = e.path.length
let labelIndex = -1
for(let i=0;i < length; i++){
if(e.path[i].className === 'labelIndex'){
labelIndex = i;
break
}
}
if(labelIndex !== -1){
console.log(e.path[labelIndex].innerText, ' =====> e.path[labelIndex].innerText')
alert('labelIndex.id = ' + e.path[labelIndex].id + ',title: ' + this.listData[e.path[labelIndex].id].title)
}else{
alert('未找到数据,请检查')
}
}
}
}
</script>
<style lang="scss" scoped>
.sn-title{
text-align: center;
}
.sn-container{
position: absolute;
left: 30%;
width: 600px;
height: 800px;
%table-style{
width: 100%;
height: 35px;
table-layout: fixed;
tr {
td {
padding: 10px 5px;
text-align: center;
background-color: transparent;
white-space: nowrap;
overflow: hidden;
color: #e200ff;
font-size: 14px;
}
}
}
.table{
.table-header{
@extend %table-style;
}
.seamless-warp{
height: 400px;
overflow: hidden;
visibility: visible;
.colorRed {
color: #FF4669;
}
.colorOrange {
color: #FFC956;
}
.item{
height: auto;
@extend %table-style;
tr{
td{
&.title{
text-overflow: ellipsis;
display: inline-block;
}
}
}
}
}
}
}
</style>