vue大屏项目中实现循环滚动

 

一,导入组件

import Banner from '@/components/banner'

components: {  banner },

 

二 在作为标签内使用   

 <banner :isHover="true" :list="bikeList" :timeSpace="3000" :showCount="count" :length="bikeList.length" v-if="bikeList.length > 0" class="warp">

                    <div class="item" v-for="(i, index) in bikeList" :key="index" @click="handleDetail(i)">

                        <div class="cItem">

                            <span>{{ i.time }}</span>

                            <span>{{ i.address }}</span>

                            <span>{{ i.carNo }}</span>

                            <span>{{ i.person }}</span>

                            <span>{{ i.behavior1 }}</span>

                        </div>

                    </div>

                </banner>

 

 

源码 如下

<template>

    <div v-bind:class="`banner ${className}`" ref="banner" v-on:mouseenter="mouseenterFunc" v-on:mouseleave="mouseleaveFunc">

        <div class="originDom" ref="originDom">

            <div class="originDomItem" ref="originDomItem" v-for="n in repeatTime" v-bind:key="n">

                <slot></slot>

            </div>

        </div>

    </div>

</template>

<script>

export default {

    props: {

        // 是否反向

        reverse: {

            type: [Boolean],

            default: function () {

                return false

            }

        },

        // 偏移的百分比

        offsetPrecent: {

            type: [Number],

            default: function () {

                return 10

            }

        },

        // 滚动模式,单条或者整页,可选值为 item 或者 page

        mode: {

            type: [String],

            default: function () {

                return 'item'

            }

        },

        // 动画的持续时间,ms为单位

        transitionDuration: {

            type: [Number],

            default: function () {

                return 500

            }

        },

        // 单条动画之间的间隔时间

        animationInterval: {

            type: [Number],

            default: function () {

                return 100

            }

        },

        // 轮播的间隔时间,ms为单位

        intervalTime: {

            type: [Number],

            default: function () {

                return 3000

            }

        },

        // 显示的条数

        showCount: {

            type: [Number],

            default: function () {

                return 3

            }

        },

        // 鼠标悬停的时候是否暂停

        hoverPause: {

            type: [Boolean],

            default: function () {

                return true

            }

        },

        // 起始模糊程度

        startBlur: {

            type: [Number],

            default: function () {

                return 0

            }

        },

        // 结束模糊程度

        endBlur: {

            type: [Number],

            default: function () {

                return 0 * window.innerHeight / 1440

            }

        },

        // 起始透明度

        startOpacity: {

            type: [Number],

            default: function () {

                return 1

            }

        },

        // 结束透明度

        endOpacity: {

            type: [Number],

            default: function () {

                return 1

            }

        },

        // 类名

        className: {

            type: [String],

            default: function () {

                return ''

            }

        },

        // 是否使用复制模式,即传入的数据小于等于要显示的条数的时候,自动复制

        repeat: {

            type: [Boolean],

            default: function () {

                return false

            }

        }

    },

    data: function () {

        return {

            msg: 'banner',

            enable: true,

            childrenDom: [],

            repeatTime: 1,

            active: 0,

            originLength: 0,

            timer: 0,

            alive: true

        }

    },

    methods: {

        mouseenterFunc: function () {

            /* eslint-disable */

            this.hoverPause && (this.enable = false)

        },

        mouseleaveFunc: function () {

            /* eslint-disable */

            this.hoverPause && (this.enable = true)

        },

        computeChildrenDom: function () {

            return new Promise(resolve => {

                if (this.$refs.originDomItem[0].children.length) {

                    let origin = [...this.$refs.originDomItem[0].children]

                    this.originLength = origin.length

                    let repeatTime = 1

                    if (!this.repeat && this.childrenDom.length < this.showCount) {

                            console.log()

                        } else {

                        while (repeatTime * this.originLength < this.showCount + 2) {

                            repeatTime = repeatTime + 1

                        }

                    }

                    this.repeatTime = repeatTime

                    this.childrenDom = []

                    this.$nextTick(() => {

                        let list = [...this.$refs.originDomItem]

                        list.forEach(item => {

                            [...item.children].forEach(dom => {

                                dom.style.position = 'absolute'

                                dom.style.transition = `all ${this.transitionDuration / 1000}s`

                                dom.style.width = '100%'

                                dom.style.opacity = 1

                                this.childrenDom.push(dom)

                            })

                        })

                        resolve()

                    })

                }

            })

        },

        computeContainerHeight: function () {

            if (!this.childrenDom.length) {

                return false

            }

            let sum = 0

            for (let i = 0; i < this.showCount; i++) {

                let index = (this.active + i) % this.childrenDom.length

                sum = sum + this.childrenDom[index].offsetHeight

            }

            /* eslint-disable */

            this.$refs.banner && (this.$refs.banner.style.height = `${sum}px`)

        },

        computeItemStyle: function () {

            if (!this.childrenDom.length) {

                return false

            }

            if (!this.repeat && this.childrenDom.length < this.showCount + 1) {

                let sum = 0

                this.childrenDom.forEach((item, index) => {

                    item.style.top = `${sum}px`

                    item.style.left = 0

                    item.style.opacity = this.startOpacity + (this.endOpacity - this.startOpacity) / (this.childrenDom.length - 1) * index

                    item.style.filter = `blur(${this.startBlur + (this.endBlur - this.startBlur) / (this.childrenDom.length - 1) * index}px)`

                    sum = sum + this.childrenDom[index].offsetHeight

                })

            } else {

                // 当使用非重复模式,并且 当前的数据数量 < 显示条数 + 1

                let sum = 0

                let indexList = []

                let prevIndex = (this.active + this.childrenDom.length - 1) % this.childrenDom.length

                let prev = this.childrenDom[prevIndex]

                prev.style.top = 0

                prev.style[this.reverse ? 'left' : 'right'] = `${this.offsetPrecent / 100 * this.$refs.banner.offsetWidth}px`

                prev.style.opacity = 0

                prev.style.pointerEvents = 'none'

                indexList.push(prevIndex)

                for (let i = 0; i < this.showCount; i++) {

                    setTimeout(() => {

                        let index = (this.active + i) % this.childrenDom.length

                        indexList.push(index)

                        this.childrenDom[index].style.top = `${sum}px`

                        this.childrenDom[index].style[this.reverse ? 'left' : 'right'] = 0

                        this.childrenDom[index].style.pointerEvents = 'auto'

                        if (this.showCount > 1) {

                            // console.log(this.startOpacity + (this.endOpacity - this.startOpacity) / (this.showCount - 1) * i)

                            this.childrenDom[index].style.opacity = this.startOpacity + (this.endOpacity - this.startOpacity) / (this.showCount - 1) * i

                            this.childrenDom[index].style.filter = `blur(${this.startBlur + (this.endBlur - this.startBlur) / (this.showCount - 1) * i}px)`

                        } else {

                            console.log(this.startOpacity)

                            this.childrenDom[index].style.opacity = this.startOpacity

                            this.childrenDom[index].style.filter = `blur(${this.startBlur}px)`

                        }

                        sum = sum + this.childrenDom[index].offsetHeight

                    }, this.animationInterval * (i + 1))

                }

                setTimeout(() => {

                    for (let i = 0; i < this.childrenDom.length; i++) {

                        if (indexList.indexOf(i) < 0) {

                            this.childrenDom[i].style[this.reverse ? 'left' : 'right'] = 0

                            this.childrenDom[i].style.top = `${sum}px`

                            this.childrenDom[i].style.opacity = 0

                            this.childrenDom[i].style.pointerEvents = 'none'

                        }

                    }

                }, this.showCount * this.animationInterval)

            }

        },

        animationFrame: function () {

            window.requestAnimationFrame(() => {

                if (this.enable) {

                    this.timer = this.timer + 1000 / 60

                    if (this.timer > this.intervalTime) {

                        this.timer = 0

                        this.active = (this.active + 1) % this.childrenDom.length

                        this.$emit('changeActive', this.active % this.originLength)

                        this.computeContainerHeight()

                        this.computeItemStyle()

                    }

                }

                /* eslint-disable */

                this.alive && this.animationFrame()

            })

        },

        init: function () {

            setTimeout(() => {

                this.computeChildrenDom().then(() => {

                    this.computeContainerHeight()

                    this.computeItemStyle()

                })

            }, 0)

        }

    },

    mounted: function () {

        this.alive = true

        /* eslint-disable */

        this.intervalTime !== 0 && this.animationFrame()

        setTimeout(() => {

            this.computeChildrenDom().then(() => {

                this.computeContainerHeight()

                this.computeItemStyle()

            })

        }, 0)

    },

    watch: {

        // activeIndex: function (newVal) {

        //     this.$emit('changeActive', (newVal + 1) % this.children.length)

        // }

    },

    beforeUpdate: function () {},

    beforeDestroy: function () {

        this.alive = false

    }

}

</script>

<style lang="less" scoped>

    .banner {

        position: relative;

        overflow: visible;

        .originDom {

            .originDomItem {

                >* {

                    opacity: 0;

                }

            }

        }

    }

</style>

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Vue 3项目大屏实现自动滚动,可以使用以下步骤: 1. 在Vue 3项目,安装vue-scrollactive插件。可以使用以下命令进行安装: ``` npm install vue-scrollactive --save ``` 2. 在主要Vue组件的script标签,引入vue-scrollactive插件。例如: ``` import Scrollactive from 'vue-scrollactive'; ``` 3. 在Vue组件的template标签,使用vue-scrollactive的v-scrollactive指令,将列元素包装在div。例如: ``` <div v-scrollactive="{offset: -200, duration: 500}"> <ul> <li>列项1</li> <li>列项2</li> <li>列项3</li> <li>列项4</li> </ul> </div> ``` 4. 在包装列的div元素上,使用v-if指令,根据需要来控制列的显示和隐藏。例如: ``` <div v-if="showList" v-scrollactive="{offset: -200, duration: 500}"> <ul> <li>列项1</li> <li>列项2</li> <li>列项3</li> <li>列项4</li> </ul> </div> ``` 5. 在Vue组件的methods,编写一个方法来控制列的显示和隐藏,以及自动滚动。例如: ``` methods: { toggleList() { this.showList = !this.showList; if (this.showList) { setTimeout(() => { this.$refs.list.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"}); }, 500); } } } ``` 6. 在Vue组件的template标签,使用按钮或其他元素来调用方法。例如: ``` <button @click="toggleList()">显示/隐藏列</button> ``` 通过以上步骤,就可以在Vue 3项目大屏实现自动滚动了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值