vue动画实现列表滚动
Vue 列表滚动动画实现方法
使用 CSS Transition 实现基础滚动
在 Vue 中可以通过结合 CSS Transition 和动态样式实现列表滚动效果。定义列表容器的固定高度和 overflow 属性,通过修改 translateY 值触发动画。
<template>
<div class="list-container" ref="container">
<div
class="list"
:style="{ transform: `translateY(${offset}px)` }"
>
<div v-for="(item, index) in list" :key="index">{{ item }}</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: ['Item 1', 'Item 2', 'Item 3', 'Item 4'],
offset: 0,
timer: null
}
},
mounted() {
this.startScroll()
},
methods: {
startScroll() {
this.timer = setInterval(() => {
this.offset -= 1
if (Math.abs(this.offset) >= this.$refs.container.scrollHeight) {
this.offset = 0
}
}, 30)
}
},
beforeDestroy() {
clearInterval(this.timer)
}
}
</script>
<style>
.list-container {
height: 200px;
overflow: hidden;
position: relative;
}
.list {
transition: transform 0.3s ease;
}
</style>
使用 Vue Transition 组件
Vue 的 <transition-group> 组件可以更方便地处理列表动画,配合 CSS 动画实现平滑滚动效果。
<template>
<div class="scroll-box">
<transition-group
tag="ul"
name="scroll"
class="list"
>
<li v-for="item in visibleItems" :key="item.id">
{{ item.text }}
</li>
</transition-group>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
],
visibleItems: []
}
},
mounted() {
this.updateVisibleItems()
setInterval(() => {
this.items.push(this.items.shift())
this.updateVisibleItems()
}, 1000)
},
methods: {
updateVisibleItems() {
this.visibleItems = [...this.items]
}
}
}
</script>
<style>
.scroll-box {
height: 120px;
overflow: hidden;
}
.list {
padding: 0;
margin: 0;
list-style: none;
}
.scroll-move {
transition: transform 0.5s;
}
</style>
使用第三方动画库
对于更复杂的动画效果,可以引入第三方动画库如 GSAP 或 anime.js 实现高性能滚动动画。
<template>
<div ref="scrollContainer" class="scroll-container">
<ul ref="list">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
</div>
</template>
<script>
import gsap from 'gsap'
export default {
data() {
return {
items: [
{ id: 1, text: 'Item A' },
{ id: 2, text: 'Item B' },
{ id: 3, text: 'Item C' }
]
}
},
mounted() {
this.animateScroll()
},
methods: {
animateScroll() {
const duration = this.items.length * 0.5
gsap.to(this.$refs.list, {
y: -this.$refs.list.offsetHeight,
duration: duration,
ease: 'none',
repeat: -1
})
}
}
}
</script>
<style>
.scroll-container {
height: 100px;
overflow: hidden;
position: relative;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
</style>
无限循环滚动优化
实现无缝循环滚动需要克隆列表元素并在适当位置重置动画,避免出现空白间隙。
<template>
<div class="viewport" ref="viewport">
<div class="list-wrapper" :style="listStyle">
<div v-for="item in duplicatedList" :key="item.id">
{{ item.text }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' }
],
scrollPosition: 0,
animationFrame: null
}
},
computed: {
duplicatedList() {
return [...this.list, ...this.list]
},
listStyle() {
return {
transform: `translateY(${-this.scrollPosition}px)`,
transition: 'transform 0.05s linear'
}
}
},
mounted() {
this.startAnimation()
},
methods: {
startAnimation() {
const step = () => {
this.scrollPosition += 1
if (this.scrollPosition >= this.$refs.viewport.scrollHeight / 2) {
this.scrollPosition = 0
}
this.animationFrame = requestAnimationFrame(step)
}
step()
}
},
beforeDestroy() {
cancelAnimationFrame(this.animationFrame)
}
}
</script>
<style>
.viewport {
height: 200px;
overflow: hidden;
position: relative;
}
.list-wrapper > div {
height: 50px;
line-height: 50px;
}
</style>
这些方法提供了不同复杂度的实现方案,从简单的 CSS 过渡到高性能的第三方动画库,可根据项目需求选择合适的方式。关键点包括容器高度控制、动画性能优化以及无缝循环处理。






