最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

vue 基于原生动画的自动滚动表格

来源:博客园


【资料图】

前言

公司展示大屏需要写滚动表格,通过滚动播放数据,自己随便摸了一个基于动画的自动滚动表格

原理

根据每行的大小和设置的每行滚动时间设置滚动位置,动态添加动画,并把数组第一项移动到最后一项,并订阅该动画结束的事件,在结束时循环执行该操作。

其他功能

  • 可自定义单元格或行
  • 可设置中文映射和取消显示
  • 单元格默认基于网格的响应式大小
  • 鼠标进入时可设置暂停

代码

<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>

参考

  • 插槽 Slots | Vue.js
  • 使用 CSS 动画 - CSS:层叠样式表 | MDN

关键词: