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

这篇具有很好参考价值的文章主要介绍了vue 基于原生动画的自动滚动表格。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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

原理

根据每行的大小和设置的每行滚动时间设置滚动位置,动态添加动画,并把数组第一项移动到最后一项,并订阅该动画结束的事件,在结束时循环执行该操作。文章来源地址https://www.toymoban.com/news/detail-445863.html

其他功能

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

代码

<template>
      <div class="title-container" v-if="!props.noTitle">
        <div
          v-for="item in props.displayTitles ?? Object.keys(props. List[0])"
          :key="item"
        >
          {{ props.titleMapping?.get(item) ?? item }}
        </div>
      </div>
    <div class="scroll-table">
      <div
        ref="container"
        class="container"
        v-on:mouseenter="() => {if(props.pauseWhenMouseEnter) animation?.pause()}"
        v-on:mouseleave="() => {if(props.pauseWhenMouseEnter) animation?.play()}"
      >
        <!-- 行插槽,作用于每个单元格,设置每个单元格的格式,设置 item-container 类型可继承组件定义的样式 -->
        <slot
          name="row"
          v-for="(item, index) in innerList"
          :key="item.id"
          :item="item"
          :index="index"
        >
          <div class="item-container">
            <!-- 默认插槽,作用于每个单元格,设置每个单元格的格式,设置 item 类型可继承组件定义的样式 -->
            <slot
              v-for="key in props.displayTitles ?? Object.keys(props.list[0])"
              :key="key"
              :item="Object.keys(item.data).includes(key) ? item.data[key] ? item.data[key] : props.undefinedPlaceholder : props.undefinedPlaceholder"
            >
              <div class="item">
                {{ Object.keys(item.data).includes(key) ? item.data[key] ? item.data[key] : props.undefinedPlaceholder : props.undefinedPlaceholder }}
              </div>
            </slot>
          </div>
        </slot>
      </div>
    </div>
</template>

<script setup lang="ts">
import BaseBox from "./BaseBox.vue";
import {
  defineProps,
  withDefaults,
  onMounted,
  computed,
  ref,
  watch,
} from "vue";
const props = withDefaults(
  defineProps<{
    // 属性名翻译为标题,默认值 属性名列表
    titleMapping?: Map<string, string>;
    // 列宽,与 grid-template-columns 格式,默认值 repeat(${props.displayTitles?.length ?? Object.keys(props.list[0]).length}, 1fr)
    columnSizes?: string;
    // 列表
    list: Array<any>;
    // 展示哪些标题,默认值 全部展示
    displayTitles?: Array<string>;
    // 走完每一行的时间,默认值 2300 ms
    interval?: number;
    // 是否显示标题行,默认值 true
    noTitle?: Boolean;
    // 属性无参数时替换为某字符串,默认值 --
    undefinedPlaceholder?: string;
    // 鼠标进入时暂停,默认值 true
    pauseWhenMouseEnter?: Boolean;
  }>(),
  {
    interval: 2300,
    noTitle: false,
    undefinedPlaceholder: "--",
    pauseWhenMouseEnter: false,
  }
);
const innerList = ref<Array<{ id: number; data: any }>>(
  props.list.map((item, index) => ({ id: index, data: item }))
);
const container = ref<HTMLDivElement>();
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<Animation>();
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>

<style scoped lang="scss">
.title-container {
  display: grid;
  padding: 1rem 0;
  font-size: 1.25rem;
  background-color: rgb(24, 34, 103);
  grid-template-columns: v-bind(columnSize);
  text-align: center;
}
:slotted(.item-container),
.item-container {
  overflow: hidden;
  position: relative;
  left: 0;
  right: 0;
  top: 0;
  display: grid;
  padding: 1rem 0;
  grid-template-columns: v-bind(columnSize);
}
:slotted(.item),
.item {
  text-align: center;
  font-size: 1.25rem;
}
.scroll-table {
  width: 100%;
  height: 100%;
  overflow: hidden;

  .container {
    overflow: hidden;
    position: relative;
    left: 0;
    right: 0;
    top: 0;
  }
}
</style>

参考

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

到了这里,关于vue 基于原生动画的自动滚动表格的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 探索 Flutter Effects: 打造生动有趣的 UI 动画

    项目地址:https://gitcode.com/HitenDev/flutter_effects Flutter 是 Google 推出的一款跨平台的移动应用开发框架,以其高效、易于学习和丰富的视觉效果赢得了开发者们的喜爱。今天,我们要向您推荐一个特别的 Flutter 项目:Flutter Effects。这是一个开源库,集合了一系列创意十足的 UI 动画

    2024年04月29日
    浏览(39)
  • vue+vant移动端显示table表格加横向滚动条

    参考文章: https://blog.csdn.net/weixin_46511008/article/details/127210738 https://my.oschina.net/u/4261744/blog/3315859 vant移动端显示table效果,增加复选框,可以进行多选和全选。加横向滚动条,可以看全部内容。 主要是参考上面两篇文章。

    2024年02月17日
    浏览(47)
  • vue+element-UI实现跟随滚动条加载表格数据

    el-table当数据量大的时候,实现滚动到底部后加载数据,直接上js代码,有其他需求请各自更改  第一步、在data中定义两个数组 第二步、在数据发生改变的方法中先循环存放一部分数据用于页面显示 第三步、在mounted监听滚动事件

    2024年02月16日
    浏览(57)
  • vue监听element-ui的table表格滚动事件

    这篇文章主要是讲述“如何监听element-ui table滚动事件”,按我自己尝试的方法去实现。 需求分析: 前两天做项目遇到一个问题,数据量大,然后表格渲染的很慢,而且很卡怎么办?有什么优化的方式? 那无非就是两种方法。 先加载一屏表格的数据,之后触底加载新的数据

    2024年02月12日
    浏览(58)
  • VUE屏幕整体滚动——滑动或滚轮(原生方法)

    一年嗖的一下儿就过去了,最近几年很流行搞年终总结,因此也研究了一下相关的内容,主要记录一下手机端与电脑端分辨通过滑动与滚轮使得整个屏幕滚动的效果 不论是使用滑动还是滚轮的方式基础的转换逻辑是相通的 首先完成页面部分的搭建,@mousewheel、@DOMMouseScroll主要

    2024年02月08日
    浏览(43)
  • vue3 如何实现 表格内容无缝滚动,我又写了一堆冗余代码

    近期在开发可视化大屏项目,除去各种 echarts 图表和地图展示之外还有多个表格。现在来了一个需求,需要将大屏中的所有表格设置为内容无缝滚动。 本着程序员的七宗罪原则第一时间推脱了一下,但没推脱成功。 简单的在网上查了下适合我们项目的有两种方案,第一种是

    2024年02月09日
    浏览(50)
  • vue | element-ui中 如何修改表格Table组件中滚动条的样式

    在Table表格中,当内容超出容器时就会出现滚动条,elemnt-ui自带的滚动条有时无法满足需求,那么我们可以通过css伪类来实现对滚动条的自定义。 滚动条由两部分组成的: 滑块:可以滑动的部分。 轨道:滚动条的轨道,即滑块的轨道。一般来说滑块的颜色比轨道的颜色深一

    2024年02月11日
    浏览(57)
  • uniapp vue3 h5,微信小程序滚动屏幕元素渐入动画&自定义导航栏

    项目文件下载地址 实际效果如下: 注意事项: animate.css需要添加样式兼容微信小程序; 微信小程序滚动时boundingClientRect获取不到标签信息 1、HBuilderX打开uniapp创建的vue3项目,在编辑器下方打开终端输入npm install animate.css --save 安装模块 animate.css官网地址 参考官方文档安装使

    2024年02月15日
    浏览(54)
  • 【VUE】实现自动滚动

    当内容超出元素固定高度时可以进行自动滚动。 首先,给需要自动滚动的元素设定统一的name,方便后续滚动方法获取元素的信息,我这里举例统一用scrollBox: 其次,给需要自动滚动的元素设置样式,要满足高度固定,超出高度时出现滚动栏: 最后,就是自动滚动方法: s

    2024年02月11日
    浏览(28)
  • JavaScript和Vue中实现表格(table)固定表头和首列【提供Vue和原生代码】

    本文主要介绍关于 JS 或 Vue 中如何进行表头,列固定,可以根据实际应用场景应用于 原生 , Vue , 移动端 , 小程序 中 实际效果展示: 对于列的固定, table 中有对应的方法,但是如果列和表头都要固定,只能通过其他方式实现,如果您找到了更好的自身方法,还请斧正 表

    2024年02月09日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包