本文实例为大家分享了vue开发实现跑马灯效果组件的具体代码,供大家参考,具体内容如下
用vue编写一个可以快进后退的跑马灯组件
由于业务需求,要实现一个会可以控制速度的跑马灯,初开始用js的setinterval每隔几毫秒来减取一个字符拼接到后面,效果不理想就放弃了。后查询用js的animate这个api改造大功告成!
效果图
组件代码
<template> ? <div class="marquee" @mouseover="pause(true)" @mouseleave="pause()"> ? ? <i ? ? ? class="marquee-btn btn-left el-icon-d-arrow-left" ? ? ? @mousedown="speedup(true)" ? ? ? @mouseup="speedstop()" ? ? ></i> ? ? <div ref="marqueetext" class="marquee-text"> ? ? ? <div v-if="itemclick"> ? ? ? ? <span ? ? ? ? ? v-for="item in text.split(splitsymbol)" ? ? ? ? ? :key="item" ? ? ? ? ? @click="$emit('itemclickevent', item)" ? ? ? ? >{{item + ' 、'}}</span> ? ? ? </div> ? ? ? <div v-else>{{text}}</div> ? ? </div> ? ? <i ? ? ? class="marquee-btn btn-right el-icon-d-arrow-right" ? ? ? @mousedown="speedup()" ? ? ? @mouseup="speedstop()" ? ? ></i> ? </div> </template> <script> export default { ? name: "marquee", ? props: { ? ? text: { ? ? ? type: string, ? ? ? required: true ? ? }, ? ? speed: { ? ? ? type: number, ? ? ? required: false, ? ? ? default: 110 ? ? }, ? ? // 是否每个都可以点击触发事件 ? ? itemclick: { ? ? ? type: boolean, ? ? ? required: false, ? ? ? default: false ? ? }, ? ? // 每个触发事件元素的分割符号 ? ? splitsymbol: { ? ? ? type: string, ? ? ? required: false, ? ? ? default: '' ? ? } ? }, ? data() { ? ? return { ? ? ? aniinstance: null, ? ? ? speedtimer: null ? ? }; ? }, ? methods: { ? ? setanimate() { ? ? ? const contentwidth = this.$refs.marqueetext.scrollwidth; ? ? ? const keyframes = [ ? ? ? ? { transform: "translatex(100%)" }, ? ? ? ? { transform: `translatex(-${contentwidth}px)` } ? ? ? ]; ? ? ? const animateoptions = { ? ? ? ? duration: (contentwidth / this.speed) * 1000, ? ? ? ? iterations: infinity, ? ? ? ? easing: "linear" ? ? ? }; ? ? ? this.aniinstance = document.queryselector(".marquee-text").animate(keyframes, animateoptions); ? ? }, ? ? /** ? ? ?* 快进 ? ? ?* @param { boolean } isleft 是否为左方向 ? ? ?*/ ? ? speedup(isleft = false) { ? ? ? const set = () => { ? ? ? ? if (this.aniinstance.currenttime > 0) { ? ? ? ? ? this.aniinstance.currenttime = this.aniinstance.currenttime + (isleft ? 2000 : -2000); ? ? ? ? ? this.aniinstance.currenttime <= 0 && (this.aniinstance.currenttime = 0); ? ? ? ? } ? ? ? } ? ? ? // 鼠标单击 ? ? ? set(); ? ? ? // 鼠标长按 ? ? ? this.speedtimer = setinterval(() => { ? ? ? ? set() ? ? ? }, 100); ? ? }, ? ? // 快进停止 ? ? speedstop() { ? ? ? clearinterval(this.speedtimer); ? ? ? this.speedtimer = null; ? ? }, ? ? /** ? ? ?* 暂停、播放 ? ? ?* @param { boolean } ispause 是否暂停 ? ? ?*/ ? ? pause(ispause = false) { ? ? ? this.aniinstance[["play", "pause"][number(ispause)]](); ? ? } ? }, ? mounted() { ? ? this.$nexttick(() => { ? ? ? this.setanimate(); ? ? }); ? } }; </script> <style lang="less" scoped> .marquee { ? position: relative; ? padding: 10px 0; ? overflow: hidden; ? width: 100%; ? font-size: 16px; ? color: #fff; ? background-image: linear-gradient( ? ? to left, ? ? #b9565e, ? ? #cb655a, ? ? #da7655, ? ? #e58a50, ? ? #eb9f4b ? ); ? &:hover .marquee-btn { ? ? opacity: 1; ? } } .marquee-btn { ? position: absolute; ? top: 50%; ? transform: translatey(-50%); ? padding: 15px; ? color: #fff; ? background: rgba(1, 1, 1, 0.4); ? z-index: 999; ? cursor: pointer; ? opacity: 0; ? transition: all 0.2s linear; } .btn-left { ? left: 0; } .btn-right { ? right: 0; } .marquee-text { ? white-space: nowrap; ? span { ? ? &:hover { ? ? ? cursor: pointer; ? ? ? color: #2c3e50; ? ? } ? } } </style>
父组件代码
<marquee ? :text="overdueinfo.content" ? :itemclick="true" ? :speed="120" ? splitsymbol="、" ? @itemclickevent="marqueesearch" ? class="marquee-box__container" ></marquee>