首页 > 其他分享 >vue 模拟滚动条循环滚动

vue 模拟滚动条循环滚动

时间:2023-07-13 17:44:54浏览次数:41  
标签:vue 滚动 timeline border height 滚动条 item state margin


<template>
    <el-card class="card-duty">
        <template #header>
            <div class="card-header">
                <span>重大警情</span>
            </div>
        </template>
        <div class="card-body" v-loading="stateMajorAlert.loading" element-loading-background="rgb(0 0 0 / 34%)">
            <div class="wrapper-timeline" @mouseenter="mouseenterEvent()" @mouseleave="mouseleaveEvent()" ref="refTimeline">
                <ul class="timeline" v-if="stateMajorAlert.majorAlertList.length > 0">
                    <li class="timeline-item" v-for="(item, index) in stateMajorAlert.majorAlertList" :key="index">
                        <div class="timeline-item__wrapper">
                            <div class="timeline-itme__header">
                                <div class="timeline-item__level">{{ item.level }}</div>
                                <div class="timeline-item__type">{{ item.type }}</div>
                                <div class="timeline-item__address">{{ item.sfdz }}</div>
                                <div class="timeline-item__ajzt">{{ item.ajztmc }}</div>
                            </div>
                            <div class="timeline-item__content">
                                <div class="timeline-item__timestamp">发生时间:{{ item.time }}</div>
                                <div class="timeline-item__nr">警情内容:{{ item.nr }}</div>
                                <div class="timeline-item__nr" v-if="item.cjczqk">出警处置情况:{{ item.cjczqk }}</div>
                                <div class="timeline-item__nr" v-if="item.jqcljgsm">警情处理结果:{{ item.jqcljgsm }}</div>
                            </div>
                        </div>
                    </li>
                </ul>
                <div v-else class="empty">暂无数据</div>
            </div>
        </div>
    </el-card>
</template>

<script setup>
import { onMounted, watch, ref, nextTick, reactive } from 'vue';
import { useMajorAlertStore } from '../../../stores/majorAlert.store';
const { stateMajorAlert, getMajorAlert } = useMajorAlertStore();
let refTimeline = ref(null);

watch(
    () => stateMajorAlert.majorAlertList,
    (val, oldVal) => {
        initTimerInterval();
    }
);

const state = reactive({
    timer: null,
    intervalTime: 30,
    config: {
        height: 0,
    },
});

// 初始化定时器
function initTimerInterval() {
    nextTick(() => {
        clearTimerEvent();

        let dom = document.querySelector('.timeline');
        const outer = refTimeline.value;
        // 如果内容高度小于外部高度,不滚动
        if (outer.clientHeight > dom.offsetHeight) {
            return;
        }
        state.config.height = dom.offsetHeight;
        state.timer = setInterval(() => {
            window.requestAnimationFrame(scroll);
        }, state.intervalTime);
    });
}
// 滚动
function scroll() {
    const DOM = refTimeline.value;
    if (DOM.scrollTop >= state.config.height - DOM.clientHeight) {
        DOM.scrollTop = 0;
        setTimeout(() => {
            window.requestAnimationFrame(scroll);
        }, state.intervalTime);

        console.log(DOM.scrollTop >= state.config.height - DOM.clientHeight, 'DOM.scrollTop >= state.config.height - DOM.clientHeight');
        return;
    }

    DOM.scrollTop++;
}
// 清除定时器
function clearTimerEvent() {
    if (state.timer) {
        clearInterval(state.timer);
        state.timer = null;
    }
}
// 鼠标移入关闭定时器
function mouseenterEvent() {
    clearTimerEvent();
}
// 鼠标移出重新调用定时器
function mouseleaveEvent() {
    initTimerInterval();
}

onMounted(() => {
    getMajorAlert();
});
</script>

<style scoped lang="scss">
.card-duty {
    width: 100%;
    height: 276px;
    margin-bottom: 10px;
}
.wrapper-timeline {
    height: 200px;
    overflow: auto;
    .timeline {
        list-style-type: none;
        color: white;
        margin: 0;
        padding: 0;
        padding-right: 10px;

        .timeline-item {
            position: relative;
            display: flex;
            // animation: marqueeAnim 5s linear 0s infinite;
            .timeline-item__wrapper {
                flex: 1;

                position: relative;
                margin-left: 6px;
                margin-bottom: 8px;
                background: rgb(10 100 195 / 20%);
                padding: unset;
                border: 1px solid #23568d;
                border-radius: 5px;

                min-height: 70px;
                padding: 12px;
                box-sizing: border-box;
                color: #ffffff;

                font-size: 14px;
                .timeline-itme__header {
                    display: flex;
                    .timeline-item__level {
                        width: 20px;
                        height: 20px;
                        background-color: #1392ce;
                        border-radius: 50%;
                        border-right: 2px solid #082c64;
                        z-index: 9;
                        text-align: center;
                        line-height: 20px;
                        font-size: 12px;
                    }

                    .timeline-item__type {
                        height: 20px;
                        line-height: 20px;
                        background-color: #1392ce;
                        margin-left: -4px;
                        padding: 0 6px;
                        margin-right: 5px;
                        font-size: 12px;
                    }
                    .timeline-item__address {
                        flex: 1;
                    }

                    .timeline-item__ajzt {
                        height: 20px;
                        line-height: 20px;
                        border: 1px solid #2ad1f3;
                        background: linear-gradient(0deg, #037099 0%, #1aa4d5 100%);
                        border-radius: 2px;
                        padding: 0 3px;
                        font-size: 12px;
                    }
                }

                .timeline-item__content {
                    margin-top: 10px;
                    margin-left: 8px;
                    .timeline-item__timestamp {
                        margin-top: 5px;
                        color: #c3d2d2;
                    }

                    .timeline-item__nr {
                        margin-top: 5px;
                        color: #c3d2d2;
                    }
                }
            }
        }
        .timeline-item::after {
            content: '';
            position: absolute;
            left: 6px;
            top: 11px;

            width: 2px;
            height: 22px;
            background: #05eaff;
        }
    }
}

::-webkit-scrollbar {
    width: 6px;
    border-radius: 3px;
}

::-webkit-scrollbar-track {
    background-color: rgb(0 20 26 / 60%);
    border-radius: 3px;
}

::-webkit-scrollbar-thumb {
    background-color: #1b6cb5;
    border-radius: 3px;
}

.empty {
    font-size: 14px;
    padding: 0;
    height: 200px;
    display: flex;
    justify-content: center;
    align-items: center;
}
</style>


标签:vue,滚动,timeline,border,height,滚动条,item,state,margin
From: https://www.cnblogs.com/lbx6935/p/17551654.html

相关文章

  • dhtmlx基本使用demo,vue
    main.js  引入样式import'dhtmlx-gantt/codebase/dhtmlxgantt.css'父组件:gangtData,数据<ganttChartv-if="value8":gangtData="gangtData"/> 子组件:<template><divstyle="height:62vh;"ref="ganttContai......
  • vue 删除对象中的属性
    data(){ return{ searchParams:{ pageSize:7, pageNum:1,isPass:'' }, list:[{ name:"全部", isPass:undefined }, { name:"待审核", isPass:1 ......
  • nginx部署 vue3 同时 配置接口代理(详细)
    Vue项目配置.env文件在项目根目录下创建文件夹(.env.production)##.env.production生产环境配置VUE_APP_SYS_URL=sysapi##nginx需要用的的代理表示VUE_APP_MODE=product##模式baseUrl使用VUE_APP_SYS_URL变量代替Nginx下载部署和配置api代理Nginx下载......
  • vue图片上传组件
    <template><[email protected]@dragenter.prevent="drag=true"@dragleave.prevent="drag=false"@drop.prevent="onDrop"@click="input.click"v-show="status==='uploa......
  • vue+vite项目在浏览器运行正常,在钉钉白屏报错,在嵌入的app里面白屏报错
    1.在钉钉直接打开本地跑的项目白屏并且报错UncaughtReferenceError:globalThisisnotdefined/@vite/client:135:7ReferenceError:globalThisisnotdefinedathttp://192.168.20.36:5173/@vite/client:135:7UncaughtSyntaxError:Unexpectedtoken./src/main.ts:19:38......
  • vue 模糊查询
    html代码<divid="root"><h3>人员列表</h3><inputtype="text"placeholder="请输入名字"v-model="keyWord"><ul><liv-for="(p,index)offilPersons"......
  • vue - 点击按钮上传文件功能的实现
    methods:{//点击调用上传方法asynchandleUpload(row){try{letfileList=awaitthis.getFile("",true);//参数1:选取文件类型如.pdf、.png、.doc文件,参数2、是否多选console.log(fileList);//上传文件可在此处进行}catch......
  • Vue 学习 Day2
    摘要:动态属性的限制当使用DOM内嵌模板(直接写在HTML文件里的模板)时,我们需要避免在名称中使用大写字母,因为浏览器会强制将其转换为小写: <a:[someAttr]="value">...</a> “someAttr”属性而非“someattr”,这段代码将不会  ......
  • vue3核心概念-Mutation-辅助函数
    你可以在组件中使用 this.$store.commit('xxx') 提交mutation,或者使用 mapMutations 辅助函数将组件中的methods映射为 store.commit 调用(需要在根节点注入 store)辅助函数只能在选项式API中使用<template><h3>Nums</h3><p>{{getCount}}</p><inputtype="......
  • Vue实现在线编辑excel、导入、导出(转)
    原文:https://www.baidu.com/link?url=AuyjwtPhSkYFpr8dpb-mdYLpniwQhc7URksdLNktJ-dFgYmR4eEv3VpuTWxEH1p37BdTjfnva4iKCX8_pZx4BgFMyFjgxtMT95FLe5N02vi&wd=&eqid=dc455e22000331bf0000000664af71c1概要Vue实现在线编辑excel、导入、导出整体架构流程luckysheet文档地址exceljs文......