vue实现列表垂直无缝滚动


Posted in Vue.js onApril 08, 2022

本文实例为大家分享了vue实现列表垂直无缝滚动的具体代码,供大家参考,具体内容如下

实现新闻列表的轮播(如下图)

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.js 相关文章推荐
在Vue中使用Echarts可视化库的完整步骤记录
Nov 18 Vue.js
vue实现广告栏上下滚动效果
Nov 26 Vue.js
Vue如何实现验证码输入交互
Dec 07 Vue.js
在vue中使用inheritAttrs实现组件的扩展性介绍
Dec 07 Vue.js
vue调用微信JSDK 扫一扫,相册等需要注意的事项
Jan 03 Vue.js
vue实现简易计算器功能
Jan 20 Vue.js
深入了解Vue动态组件和异步组件
Jan 26 Vue.js
vue如何批量引入组件、注册和使用详解
May 12 Vue.js
vue使用节流函数的踩坑实例指南
May 20 Vue.js
vue+springboot实现登录验证码
May 27 Vue.js
vue中this.$http.post()跨域和请求参数丢失的解决
Apr 08 Vue.js
vue配置型表格基于el-table拓展之table-plus组件
Apr 12 Vue.js
vue3引入highlight.js进行代码高亮的方法实例
vue中的可拖拽宽度div的实现示例
vue 实现弹窗关闭后刷新效果
Apr 08 #Vue.js
vue中this.$http.post()跨域和请求参数丢失的解决
Apr 08 #Vue.js
vue实现书本翻页动画效果实例详解
Apr 08 #Vue.js
vue实现列表拖拽排序的示例代码
vue实现可以快进后退的跑马灯组件
Apr 08 #Vue.js
You might like
PHP文本操作类
2006/11/25 PHP
第4章 数据处理-php数组的处理-郑阿奇
2011/07/04 PHP
php获取CSS文件中图片地址并下载到本地的方法
2014/12/02 PHP
最新制作ThinkPHP3.2.3完全开发手册
2015/11/23 PHP
PHP从零开始打造自己的MVC框架之入口文件实现方法详解
2019/06/03 PHP
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
jquery中each方法示例和常用选择器
2014/07/08 Javascript
超级简单实现JavaScript MVC 样式框架
2015/03/24 Javascript
jQuery表格行上移下移和置顶的实现方法
2015/10/08 Javascript
在JavaScript中如何解决用execCommand(
2015/10/19 Javascript
基于Jquery easyui 选中特定的tab
2015/11/17 Javascript
常见JS验证脚本汇总
2015/12/01 Javascript
一个非常好用的文字滚动的案例,鼠标悬浮可暂停[两种方案任选]
2016/12/01 Javascript
js判断手机号是否正确并返回的实现代码
2017/01/17 Javascript
微信小程序实现跑马灯效果完整代码(附效果图)
2018/05/30 Javascript
初探Vue3.0 中的一大亮点Proxy的使用
2018/12/06 Javascript
使用python 获取进程pid号的方法
2014/03/10 Python
Python实现的二维码生成小软件
2014/07/11 Python
python+matplotlib绘制饼图散点图实例代码
2018/01/20 Python
Python图像处理之简单画板实现方法示例
2018/08/30 Python
python 通过视频url获取视频的宽高方式
2019/12/10 Python
python+OpenCV实现图像拼接
2020/03/05 Python
python 的topk算法实例
2020/04/02 Python
python根据完整路径获得盘名/路径名/文件名/文件扩展名的方法
2020/04/22 Python
解决使用Pandas 读取超过65536行的Excel文件问题
2020/11/10 Python
小学生自我评价范例
2013/09/24 职场文书
行政文员岗位职责
2013/11/08 职场文书
怎样写演讲稿
2014/01/04 职场文书
歌颂祖国的演讲稿
2014/05/04 职场文书
运动会演讲稿300字
2014/08/25 职场文书
党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
2015毕业实习推荐信
2015/03/23 职场文书
拾金不昧表扬稿大全
2015/05/05 职场文书
钢铁是怎样炼成的读书笔记
2015/06/29 职场文书
JPA 通过Specification如何实现复杂查询
2021/11/23 Java/Android
MySQL数据库完全卸载的方法
2022/03/03 MySQL