Posted in Vue.js onApril 08, 2022
本文实例为大家分享了vue实现列表垂直无缝滚动的具体代码,供大家参考,具体内容如下
实现新闻列表的轮播(如下图)
上代码
封装的so-marquee.vue
<template>
<div
class="marquee-wrapper"
:style="{ width: realWidth + 'px' }"
>
<div
class="marquee-container"
:style="{ height: realHeight + 'px' }"
:class="className"
>
<ul
ref="marqueeCon"
:id="tooltipId"
class="marquee-content"
:class="{ anim: animate === true}"
@mouseenter="handleStop()"
@mouseleave="handleUp()"
>
<li
v-for="(item,index) in realData"
:key="`${tooltipId}-${item.id}-${index}`"
class="marquee-item"
:style="{ height: itemHeigth + 'px' }"
@click="handleClick(item)"
>
<slot name="itemCon" :item="item"></slot>
</li>
</ul>
</div>
</div>
</template>
<script>
import { parseToNum, generateId } from '@/utils/util'
export default {
name: "so-marquee",
props: {
/*
* 可接受传参
* data 列表数据
* className 自定义类名
* width 列表宽度,默认值:400
* height 列表高度,默认值:200
* showNumber 可视的条目数,默认值:5
* speed 轮播速度,默认值:1000
* */
//列表数据
data: {
type: Array,
default: () => [],
},
//自定义类名
className: String,
//列表宽度,默认值:400
width: {
type: [Number, String],
default: 400
},
//列表高度,默认值:200
height: {
type: [Number, String],
default: 200
},
//可视的条目数,默认值:5
showNumber: {
type: [Number, String],
default: 5
},
//轮播速度,默认值:1000
speed: {
type: [Number, String],
default: 1000
}
},
data() {
return {
intnum: undefined,
animate: false
};
},
computed: {
tooltipId() {
return `marquee-con-${ generateId() }`;
},
realWidth() {
return parseToNum(this.width)
},
realHeight() {
return parseToNum(this.height)
},
realShowNumber() {
return parseToNum(this.showNumber)
},
realSpeed() {
return parseToNum(this.speed) < 1000 ? 1000 : parseToNum(this.speed)
},
itemHeigth() {
return this.realHeight / this.realShowNumber
},
realData() {
return JSON.parse(JSON.stringify(this.data))
}
},
mounted() {
if (this.realData.length > this.realShowNumber) {
this.scrollUp();
}
},
methods: {
scrollUp() {
// eslint-disable-next-line no-unused-vars
this.intnum = setInterval(_ => {
this.animate = true;
setTimeout(() => {
this.realData.push(this.realData[0]); // 将数组的第一个元素添加到数组的
this.realData.shift(); //删除数组的第一个元素
this.animate = false; // margin-top 为0 的时候取消过渡动画,实现无缝滚动
}, this.realSpeed / 2)
this.$once('hook:beforeDestroy', () => {
this.cleanup()
})
}, this.realSpeed);
},
handleStop() {
this.cleanup()
},
handleUp() {
this.scrollUp();
},
handleClick(row) {
this.$emit('handleClick', row)
},
cleanup() {
if (this.intnum) {
clearInterval(this.intnum);
this.intnum = null;
}
}
},
beforeDestroy() {
this.cleanup();
},
deactivated() {
this.cleanup();
},
watch: {
animate(flag) {
this.marqueeCon = this.$refs.marqueeCon
if (flag) {
this.marqueeCon.style.marginTop = `-${ this.itemHeigth }px`
} else {
this.marqueeCon.style.marginTop = 0
}
},
}
};
</script>
<style scoped lang="scss">
.marquee-container {
overflow: hidden;
}
.marquee-content {
position: relative;
}
.anim {
transition: all 0.5s;
}
.marquee-item {
display: flex;
align-items: center;
justify-content: space-around;
}
</style>
parseToNum方法
export function parseToNum(value) {
if (value !== undefined) {
value = parseInt(value, 10)
if (isNaN(value)) {
value = null;
}
}
return value
}
generateId 方法
export const generateId = function() {
return Math.floor(Math.random() * 10000);
};
父组件调用
<template>
<div id="app">
<so-marquee
:data="jsonData"
:height="200"
:showNumber="4"
:speed="500"
class="my-ui-marquee"
@handleClick="handleMarqueeClick"
>
<template v-slot:itemCon="{item}">
<div>{{ item.id }}</div>
<div>{{ item.name }}</div>
<div>{{ item.date }}</div>
</template>
</so-marquee>
</div>
</template>
<script>
import soMarquee from './components/so-marquee'
export default {
name: 'App',
data() {
return {
jsonData: [
{
id: 1,
name: "开会通知",
date: "2020-02-01"
},
{
id: 2,
name: "放假通知",
date: "2020-02-02"
},
{
id: 3,
name: "停水通知",
date: "2020-02-03"
},
{
id: 4,
name: "停电通知",
date: "2020-02-04"
},
{
id: 5,
name: "停车通知",
date: "2020-02-05"
},
{
id: 6,
name: "奖励通知",
date: "2020-02-06"
},
{
id: 7,
name: "处分通知",
date: "2020-02-07"
},
{
id: 8,
name: "处分8通知",
date: "2020-02-08"
},
{
id: 9,
name: "处分9通知",
date: "2020-02-09"
},
{
id: 10,
name: "处分10通知",
date: "2020-02-10"
},
]
}
},
components: {
soMarquee
},
methods: {
handleMarqueeClick(row) {
alert(`当前点击的第${row.id}行`)
}
}
}
</script>
<style scoped lang="scss">
.my-ui-marquee {
::v-deep.marquee-item {
cursor: pointer;
}
}
</style>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。
vue实现列表垂直无缝滚动
- Author -
杨阳洋- Original Sources -
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@