<template>
<div>
<Marquee :speed="100">
<div>跑马灯内容1</div>
<div>跑马灯内容2</div>
<div>跑马灯内容3</div>
</Marquee>
</div>
</template>
<script>
import Marquee from './components/Marquee.vue'
export default {
name: 'App',
components: {
Marquee
}
}
</script>
<template>
<div class="marquee-outer" ref="marqueeOuter">
<div
class="marquee-inner"
:style="{ transform: `translateX(${translateX}px)` }"
>
<!-- <slot />
<slot /> -->
<div>跑马灯内容1</div>
<div>跑马灯内容2</div>
<div>跑马灯内容3</div>
</div>
</div>
</template>
<script>
import { ref, watch } from 'vue'
export default {
name: 'Marquee',
props: {
speed: {
type: Number,
default: 50 // 默认速度为50px/s
}
},
setup(props) {
const marqueeOuter = ref(null)
const marqueeWidth = ref(0)
const translateX = ref(0)
// 获取跑马灯容器的宽度
function getMarqueeWidth() {
if (marqueeOuter.value) {
marqueeWidth.value = marqueeOuter.value.offsetWidth
}
}
// 监听子节点变化,更新跑马灯容器的宽度
watch(
() => marqueeOuter.value.children,
() => {
getMarqueeWidth()
}
)
// 滚动跑马灯
function scrollMarquee() {
if (translateX.value > -marqueeWidth.value) {
translateX.value -= props.speed / 60 // 每秒滚动props.speed个像素
requestAnimationFrame(scrollMarquee)
} else {
// 跑马灯滚动完成
translateX.value = marqueeWidth.value
}
}
return {
marqueeOuter,
marqueeWidth,
translateX,
getMarqueeWidth,
scrollMarquee
}
},
mounted() {
this.getMarqueeWidth()
this.scrollMarquee()
}
}
</script>
<style>
.marquee-outer {
position: relative;
display: flex;
overflow: hidden;
}
.marquee-inner {
display: flex;
}
/* 子元素样式,可根据实际需求修改 */
.marquee-inner > * {
margin-right: 20px;
}
</style>