【资料图】
公司展示大屏需要写滚动表格,通过滚动播放数据,自己随便摸了一个基于动画的自动滚动表格
根据每行的大小和设置的每行滚动时间设置滚动位置,动态添加动画,并把数组第一项移动到最后一项,并订阅该动画结束的事件,在结束时循环执行该操作。
{{ props.titleMapping?.get(item) ?? item }} {{ Object.keys(item.data).includes(key) ? item.data[key] ? item.data[key] : props.undefinedPlaceholder : props.undefinedPlaceholder }} <script setup lang="ts">import BaseBox from "./BaseBox.vue";import { defineProps, withDefaults, onMounted, computed, ref, watch,} from "vue";const props = withDefaults( defineProps<{ // 属性名翻译为标题,默认值 属性名列表 titleMapping?: Map; // 列宽,与 grid-template-columns 格式,默认值 repeat(${props.displayTitles?.length ?? Object.keys(props.list[0]).length}, 1fr) columnSizes?: string; // 列表 list: Array; // 展示哪些标题,默认值 全部展示 displayTitles?: Array; // 走完每一行的时间,默认值 2300 ms interval?: number; // 是否显示标题行,默认值 true noTitle?: Boolean; // 属性无参数时替换为某字符串,默认值 -- undefinedPlaceholder?: string; // 鼠标进入时暂停,默认值 true pauseWhenMouseEnter?: Boolean; }>(), { interval: 2300, noTitle: false, undefinedPlaceholder: "--", pauseWhenMouseEnter: false, });const innerList = ref>( props.list.map((item, index) => ({ id: index, data: item })));const container = ref();onMounted(() => { animate(true);});// 监控数据列表更新watch( () => props.list, () => { innerList.value = props.list.map((item, index) => ({ id: index, data: item, })); });// 计算列大小const columnSize = computed(() => { return ( props.columnSizes ?? `repeat(${ props.displayTitles?.length ?? Object.keys(props.list[0]).length }, 1fr)` );});// 进行动画const animation = ref();const animate = (isStart = false) => { // 计算动画高度 let height = 0; if (!isStart) { height = -container.value!.children[1].getBoundingClientRect().height; // 移动数组第一个到最后一个 let temp = innerList.value.shift(); innerList.value.push(temp!); } else { height = -container.value!.children[0].getBoundingClientRect().height; } // 进行动画 animation.value = container.value!.animate( [ { top: `${height}px`, }, ], { duration: props.interval, iterations: 1, } ); // 监听动画完成后,重新开始动画 animation.value.addEventListener("finish", () => animate(false));};</script>
标签:
X 关闭
X 关闭