【可视化】封装滚动菜单列表组件

news2025/2/5 10:40:40

在这里插入图片描述
在这里插入图片描述

源码及源码分析


<template>
  <!-- 滚动菜单的主要容器 -->
  <div class="scrolling-menu">
    <!-- 如果headers数组有内容,就渲染表头 -->
    <div
      class="table-header"
      v-if="headers.length"
      :style="{ backgroundColor: headerBackground }"
    >
      <!-- 遍历表头的每一个项,并渲染 -->
      <div
        class="header-item"
        v-for="(header, index) in headers"
        :key="index"
        :style="getHeaderStyle()"
      >
        {{ header }}
      </div>
    </div>
    <!-- 表体部分,包含所有的表项 -->
    <div class="table-body" ref="menuContainer">
      <!-- 遍历当前展示的items,并渲染 -->
      <div
        class="menu-item"
        v-for="(item, index) in displayedItems"
        :key="index"
        :style="getItemStyle(index)"
      >
        <!-- 根据配置的列,渲染每一列的数据 -->
        <div
          v-for="(field, colIndex) in columns"
          :key="colIndex"
          class="column-item"
          style="color: aliceblue;"
          :style="getColumnStyle()"
        >
          {{ formatItem(item, field) }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, defineProps } from 'vue';

const props = defineProps({
  data: {
    type: Array, // 传入的数据数组
    required: true, // 必须传入该数据
  },
  headers: {
    type: Array, // 表头内容
    default: () => [], // 如果没有传入,则为空数组
  },
  columns: {
    type: Array, // 显示数据的列名
    required: true, // 必须传入
  },
  rows: {
    type: Number, // 显示的行数
    default: 5, // 默认显示5行
  },
  scrollSpeed: {
    type: Number, // 滚动速度,单位为毫秒
    default: 3000, // 默认每隔3000ms滚动一次
  },
  itemFormatter: {
    type: Function, // 自定义数据格式化函数
    default: (item, field) => item[field]?.toString() || '', // 默认返回对应字段的值,如果不存在则为空字符串
  },
  rowHeight: {
    type: String,
    default: '20%', // 每行高度占父容器的20%,即5行平均分配
  },
  fontSize: {
    type: String,
    default: '16px', // 默认字体大小
  },
  textAlign: {
    type: String,
    default: 'center', // 默认文字居中对齐
  },
  headerBackground: {
    type: String,
    default: 'rgba(0, 0, 50, 0.5)', // 表头背景色
  },
  rowBackground: {
    type: String,
    default: 'rgba(0, 0, 50, 0.2)', // 行背景色
  },
  alternateRowBackground: {
    type: String,
    default: 'rgba(62, 62, 173, 0.2)', // 每隔一行的背景色
  },
});

const menuContainer = ref(null); // 获取表体的引用
const displayedItems = ref([]); // 当前显示的行项

let interval = null; // 存储setInterval的引用,用于清除
let currentIndex = 0; // 当前滚动的起始索引

const startScrolling = () => {
  // 开始自动滚动
  interval = setInterval(() => {
    currentIndex += props.rows; // 每次滚动显示rows数量的数据
    if (currentIndex >= props.data.length) {
      // 如果到达数据末尾,回到起始位置
      currentIndex = 0;
    }
    updateDisplayedItems(); // 更新当前显示的项
  }, props.scrollSpeed);
};

const updateDisplayedItems = () => {
  // 更新显示的数据项,切片当前的rows个数据
  displayedItems.value = props.data.slice(currentIndex, currentIndex + props.rows);
};

const formatItem = (item, field) => {
  // 使用自定义的格式化函数,格式化每个数据项
  return props.itemFormatter(item, field);
};

const getHeaderStyle = () => {
  // 获取表头样式
  return {
    width: `${100 / props.columns.length}%`, // 宽度根据列的数量平分
    fontSize: props.fontSize,
    textAlign: props.textAlign,
  };
};

const getItemStyle = (index) => {
  // 获取每行的样式
  return {
    display: 'flex',
    width: '100%',
    height: props.rowHeight,
    backgroundColor: index % 2 === 0 ? props.rowBackground : props.alternateRowBackground, // 根据行的索引决定背景颜色
  };
};

const getColumnStyle = () => {
  // 获取每列的样式
  return {
    width: `${100 / props.columns.length}%`, // 宽度根据列的数量平分
    fontSize: props.fontSize,
    textAlign: props.textAlign,
  };
};

onMounted(() => {
  // 组件挂载后,初始化显示的数据并开始滚动
  updateDisplayedItems();
  startScrolling();
});

onUnmounted(() => {
  // 组件卸载前,清除滚动的定时器
  clearInterval(interval);
});

watch(
  () => props.data, // 监听数据变化
  () => {
    // 当数据变化时,重置索引并更新显示项
    currentIndex = 0;
    updateDisplayedItems();
  }
);
</script>

<style scoped>
.scrolling-menu {
  display: flex;
  flex-direction: column; /* 使子元素垂直排列 */
  overflow: hidden; /* 隐藏溢出的内容 */
  width: 100%;
  height: 100%;
}

.table-header {
  display: flex;
  padding: 10px;
  font-weight: bold; /* 表头字体加粗 */
  color: white;
}

.header-item {
  text-align: center; /* 表头项居中对齐 */
}

.table-body {
  display: flex;
  flex-direction: column;
  flex-grow: 1; /* 表体部分填充剩余空间 */
  overflow: hidden; /* 隐藏溢出的内容 */
}

.menu-item {
  display: flex;
  align-items: center;
  justify-content: space-between; /* 在行内的列之间均匀分布 */
  box-sizing: border-box; /* 包括边框和内边距在内的大小计算方式 */
}
</style>




代码逻辑解析
Props定义: 组件接收多种参数用于自定义显示效果,比如 data (数据数组), headers (表头数组), columns (要显示的列), rows (显示的行数), scrollSpeed (滚动速度), 等等。这些参数让组件在不同的使用场景中保持灵活性。

Data定义: displayedItems 是一个 ref,用来存放当前显示的表项。menuContainer 是一个 ref,指向表体部分的 DOM 元素。

startScrolling函数: 通过 setInterval 实现自动滚动的效果,每隔 scrollSpeed 毫秒更新显示的项。当 currentIndex 达到数据长度的末尾时,会重置为 0,实现循环滚动。

updateDisplayedItems函数: 这个函数根据 currentIndex 来更新 displayedItems,只显示 rows 数量的数据。

getHeaderStyle函数和getItemStyle函数: 用来动态生成样式,确保组件的每一列和每一行都能根据传入的参数灵活调整。

生命周期钩子:

在 onMounted 中,组件加载后初始化显示的数据并开始滚动。
在 onUnmounted 中,组件卸载前清除定时器,防止内存泄漏。
数据监听: 使用 watch 监听 props.data,当数据发生变化时,重置索引并重新渲染显示项。

滚动菜单列表组件使用文档


目录
  1. 概述
  2. 安装
  3. 快速开始
  4. API 参考
    • Props
    • Slots
    • Events
  5. 示例
  6. 常见问题

概述

滚动菜单列表组件是一个适用于大屏可视化项目的自定义组件。它支持自定义表格头部、多种数据格式、自动滚动显示数据,并具有高度的灵活性和可配置性。无论是单列数据还是多列数据,都可以通过简单配置快速展示,并且支持自定义样式以匹配不同的视觉风格。


安装

  1. 通过 npm 安装:

    npm install vue-scroll-menu-list --save
    
  2. 通过 yarn 安装:

    yarn add vue-scroll-menu-list
    

快速开始

在 Vue 项目中使用滚动菜单列表组件:

<template>
  <ScrollMenuList 
    :data="menuData"
    :headers="['项目名称', '漏洞数量', '严重等级']"
    :columns="['name', 'count', 'severity']"
    :rows="5"
    :scrollSpeed="3000"
    :itemFormatter="formatMenuItem"
    rowHeight="19%"
    fontSize="18px"
    textAlign="center"
    headerBackground="rgba(10, 10, 50, 0.7)"
    rowBackground="rgba(0, 0, 50, 0.3)"
    alternateRowBackground="rgba(62, 62, 173, 0.3)"
  />
</template>

<script>
import ScrollMenuList from 'vue-scroll-menu-list';

export default {
  components: { ScrollMenuList },
  data() {
    return {
      menuData: [
        { name: '项目A', count: 100, severity: '高' },
        { name: '项目B', count: 200, severity: '中' },
        // 更多数据...
      ],
    };
  },
  methods: {
    formatMenuItem(item, field) {
      return item[field] || '-';
    }
  }
};
</script>

API 参考

Props
Prop 名称类型默认值说明
dataArray[]必需。要显示的数据列表。每个对象表示一行数据。
headersArray[]可选。表头名称列表。与 columns 对应,若为空则不显示表头。
columnsArray[]必需。要显示的列名列表,定义每列对应的数据字段。
rowsNumber5显示的行数。默认为5。
scrollSpeedNumber3000可选。自动滚动的速度,单位为毫秒。
itemFormatterFunction`(item, field) => item[field]?.toString()
rowHeightString'20%'可选。每行的高度,支持百分比或像素值,默认为父容器高度的20%。
fontSizeString'16px'可选。表格文字的大小。
textAlignString'center'可选。文字对齐方式。可以是 'left', 'center', 'right'
headerBackgroundString'rgba(0, 0, 50, 0.5)'可选。表头背景颜色。
rowBackgroundString'rgba(0, 0, 50, 0.2)'可选。表格行的背景颜色。
alternateRowBackgroundString'rgba(62, 62, 173, 0.2)'可选。表格隔行背景颜色。

示例

<template>
  <ScrollMenuList 
    :data="menuData"
    :headers="['项目名称', '漏洞数量', '严重等级']"
    :columns="['name', 'count', 'severity']"
    :rows="5"
    :scrollSpeed="3000"
    :itemFormatter="formatMenuItem"
    rowHeight="19%"
    fontSize="18px"
    textAlign="center"
    headerBackground="rgba(10, 10, 50, 0.7)"
    rowBackground="rgba(0, 0, 50, 0.3)"
    alternateRowBackground="rgba(62, 62, 173, 0.3)"
  />
</template>

<script>
export default {
  data() {
    return {
      menuData: [
        { name: '项目A', count: 100, severity: '高' },
        { name: '项目B', count: 200, severity: '中' },
        { name: '项目C', count: 150, severity: '低' },
        // 更多数据...
      ],
    };
  },
  methods: {
    formatMenuItem(item, field) {
      return item[field] || '-';
    }
  }
};
</script>

常见问题

  1. 组件不滚动: 检查 scrollSpeed 是否设置过长或者数据量是否不足以触发滚动。
  2. 自定义样式未生效: 请确保传入的 props 符合组件要求,并且样式值合法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2056757.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLM向量嵌入知多少

向量嵌入是机器学习领域中一项引人入胜且极具实用性的技术。它们构成了众多自然语言处理&#xff08;NLP&#xff09;、推荐系统和搜索算法的基础。如果您曾经使用过推荐引擎、语音助手或语言翻译工具&#xff0c;那么您已经体验过嵌入技术的强大功能。 机器学习算法&#xff0…

如何为您的专用IP地址选择正确的IP SSL证书

随着互联网的不断发展&#xff0c;网站安全变得越来越重要。SSL证书不仅为网站提供了加密通道&#xff0c;还增强了用户对网站的信任感。对于那些使用专用IP地址的网站来说&#xff0c;选择合适的IP SSL证书至关重要。本文将为您详细介绍如何挑选最适合您网站需求的IP SSL证书。…

Cocos Creator2D游戏开发(14)---CocosCreator常用组件详解

Canvas RenderRoot2D 组件所在的节点是 2D 渲染组件数据收集的入口,而 Canvas&#xff08;画布&#xff09; 组件继承自 RenderRoot2D 组件&#xff0c;所以 Canvas 组件也是数据收集入口。所有 2D 渲染元素都必须作为 RenderRoot2D 的子节点才能被渲染。 Canvas还作为屏幕适配…

Web基础、http协议、源码编译构建LAMP

目录 一、DNS与域名 1.1域名概述 1.2域名小结 1.3DNS域名解析 1.4域名 二、网页的概念 1.网页的基本概念 三、web 1.1web概述 1.2渲染过程 1.3web1.0和web2.0 1.4静态页面和动态页面 四、http协议 1.http协议简介 2.cookie和session 2.1cookie 2.2session 3.c…

React学习笔记(一)——react基础

1. React 介绍 1.1 React是什么 React由Meta公司研发&#xff0c;是一个用于 构建Web和原生交互界面的库 1.2 React的优势 相较于传统基于DOM开发的优势&#xff1a; 组件化的开发方式不错的性能 相较于其它前端框架的优势&#xff1a; 丰富的生态跨平台支持 1.3 React的市场…

国内知名电器集团售后服务系统被黑!损失1.2亿!

两款软件入侵 近期&#xff0c;一款名为“A助手”的软件和另一款“B配置工具”被揭露存在严重的非法活动。 这两款软件被不法分子利用&#xff0c;并成功侵入了某知名企业的电器售后服务系统。通过技术手段&#xff0c;伪造了电器安装服务的工单&#xff0c;并以此骗取了大量的…

24年银行从业资格考试报名照规格要求

24年银行从业资格考试报名照规格要求 #银行从业 #银行从业资格证 #银行从业考试 #银行从业资格考试 #银行从业资格证报名照片 #银从

Unity 波函数坍缩算法随机地图生成

Unity 波函数坍缩算法随机地图生成 波函数波函数基本概念位置空间波函数动量空间波函数两种波函数之间的关系波函数的本征值和本征态波函数坍缩 熵是什么熵作为状态函数时间之箭 实现原理举个例子&#xff1a;2D迷宫地图生成 Unity 如何实现前期准备单元格代码瓦片地图代码波函…

使用亮数据爬虫工具解锁复杂爬虫场景

在当今数据驱动型时代&#xff0c;数据采集和分析能力算是个人和企业的核心竞争力。然而&#xff0c;手动采集数据耗时费力且效率低下&#xff0c;而且容易被网站封禁。 我之前使用过一个爬虫工具&#xff0c;亮数据&#xff08;Bright Data&#xff09; &#xff0c;是一款低…

PCIe学习笔记(25)

数据完整性 PCI Express的基本数据可靠性机制包含在数据链路层(data Link Layer)中&#xff0c;它使用32位的LCRC (CRC)码逐链路检测TLP中的错误&#xff0c;并采用逐链路重传机制进行错误恢复。TLP是一个数据和事务控制单元&#xff0c;由位于PCI Express域“边缘”的数据源(…

重大发现!看Apache与nginx工作模型,享web服务幸福人生

文章目录 文章相关连接如下&#xff1a; Web 服务基础介绍ApacheApache prefork 模型 Apache worker 模型Apache event模型 Nginx-高性能的 Web 服务端nginx源码安装平滑升级和回滚平滑升级步骤&#xff1a;回滚步骤 nginx启动文件 文章相关连接如下&#xff1a; 如果想更多了…

【GH】【EXCEL】P4: Chart

文章目录 data and chartdonut chart (radial chart)Radial Chart bar chartBar Chart line chartLine Chart Scatter ChartScatter Chart Surface ChartSurface Chart Chart DecoratorsChart Decorators Chart GraphicsChart Graphics data and chart donut chart (radial cha…

《面板变系数模型及 Stata 具体操作步骤》

目录 一、文献综述 二、理论原理 三、实证模型 四、稳健性检验 五、程序代码及解释 六、代码运行结果 一、文献综述 在经济和社会科学研究领域&#xff0c;面板数据模型因其能够同时考虑个体和时间维度的信息而被广泛应用。传统的面板数据模型通常假设系数是固定的&#…

1.初识redis

文章目录 1.认识redis1.1 mysql和redis 对比1.2分布式系统1.2.1单机架构与分布式架构1.2.2数据库分离(应用服务器和存储服务器分离)与负载均衡1.2.3负载均衡器1.2.4 数据库读写分离1.2.5 数据库服务器引入缓存1.2.6数据库分库分表1.2.7 引入微服务 2.常见概念解释2.1 应用(Appl…

GoModule

GOPATH 最早的就是GOPATH构建模式&#xff0c; go get下载的包都在path中的src目录下 src目录是源代码存放目录。 package mainimport ("net/http""github.com/gorilla/mux" )func main() {r : mux.NewRouter()r.HandleFunc("/hello", func(w h…

iptables流量走向图

关联教学 https://www.bilibili.com/video/BV1dw411J7Qk/?spm_id_from333.337.search-card.all.click

7.2 算法设计与分析

分治法&#xff08;考的概率较低&#xff09; 回溯法&#xff08;考的概率较低&#xff09; 动态规划法&#xff08;考的概率较高&#xff09; 1

第四届机电一体化、自动化与智能控制国际学术会议(MAIC 2024)

目录 大会官网 会议简介 组织机构 大会主席 程序委员会主席 主讲嘉宾 征稿主题 参会说明 大会官网 http://www.icmaic.org 会议简介 第四届机电一体化、自动化与智能控制国际学术会议&#xff08;MAIC 2024&#xff09;将于2024年9月27-29日在中国成都召开。MAIC 20…

高性能MySQL04_操作系统和硬件优化

1. 从软件本身和它运行的典型工作负载来看&#xff0c;MySQL通常也更适合运行在廉价硬件上 2. 基本资源 2.1. CPU 2.2. 内存 2.3. 磁盘 2.4. 瓶颈 2.5. 网络资源 3. CPU 3.1. 最常见的瓶颈是CPU耗尽 3.2. 检查CPU使用率来确定工作负载是否受CPU限制 3.3. 低延迟&…

机器人学——正向运动学(机械臂)

Manipulator Forward Kinematics 机械臂基础概念 Joint and Link 连杆长度、连杆夹角 连杆偏距与关节角 移动关节看距离、旋转关节看角度 如何在杆上建立坐标系 地杆&#xff08;link0&#xff09;坐标系的建立 末端杆件坐标系的建立 DH表达法 如何计算出两杆之间的变换矩阵…