当前位置: 首页 > news >正文

vue3+ts 实现时间间隔选择器

  • 需求背景
  • 解决效果
  • 视频效果
  • balancedTimeElement.vue

需求背景

实现一个分片的时间间隔选择器,需要把显示时间段显示成图表,涉及一下集中数据转换

  • [“02:30-05:30”,“07:30-10:30”,“14:30-17:30”]
  • ‘[(2,5),(7,10),(14,17)]’
  • [4, 5, 6, 7, 8, 9, 10, 14, 15, 16, 17, 18, 19, 20, 28, 29, 30, 31, 32, 33, 34]

解决效果

在这里插入图片描述

视频效果

时间间隔选择器

balancedTimeElement.vue

<!--/*** @author: liuk* @date: 2023/11/28* @describe: 时间间隔选择器* @CSDN:https://blog.csdn.net/hr_beginner?type=blog*/-->
<template><div><div class="hours-container"><div class="hours-item-header-box"><div class="hours-item-header" v-for="(_, i) in hours.slice(0,24)" :key="i">{{(i + 1 + '').padStart(2, 0)}}</div></div><div class="hours-item-box" ref="hoursItemRef"><template v-for="(_, i) in hours" :key="i"><div class="hours-item" :class="compClass(i)" @click="handleClick(i)" @mouseover="handleHover(i)"></div></template></div></div><div class="tips">提示: 向右选中,向左取消选择</div></div>
</template><script lang="ts" setup>
import {reactive, toRefs, ref, watch} from "vue";// Props
const props = defineProps(['manual_period'])// Emits
const emit = defineEmits(['data-passed'])// Ref
const hoursItemRef = ref(null)type numOrstr = number | string
type arrOrstr = any[] | stringinterface ModelType {hours: number[]selectStart: booleanstartIndex: numOrstrtimeRangeList: string[]timeRangeListIndex: numOrstr[]tempRangeIndex: number[]tips: arrOrstr
}const model: ModelType = reactive({hours: new Array(48).fill('').map((_, i) => i),selectStart: false,// 开始startIndex: '',// 开始下标timeRangeList: [],// 选择的时间段timeRangeListIndex: [],// 选中的下标tempRangeIndex: [],// 预选下标tips: '',})
const {hours,selectStart,startIndex,timeRangeList,timeRangeListIndex,tempRangeIndex,tips,
} = toRefs(model)watch(() => props.manual_period, (data) => {//'[(2,5),(7,10),(14,17)]'const str = data.replace(/\(|\)/g, (val) => { // '[[2,5],[7,10],[14,17]]'switch (val) {case "(":return "["case ")":return "]"}})model.timeRangeListIndex = JSON.parse(str).map(item => {const [x, y] = itemreturn new Array(2 * y - 2 * x + 1).fill(0).map((_, i) => i + 2 * x)}).flat()//  [4, 5, 6, 7, 8, 9, 10, 14, 15, 16, 17, 18, 19, 20, 28, 29, 30, 31, 32, 33, 34]Array.from(hoursItemRef.value.children).forEach((dom: HTMLDivElement, index) => {if (model.timeRangeListIndex.includes(index)) {dom.className += ' selected'}})
})// 下标区间转换成时间区间
const transformedSection = () => {model.timeRangeList = [];let startTime = '', endTime = '', len = model.hours.length;for (let index = model.hours[0] * 2; index < 2 * (len + 1); index++) {if (model.timeRangeListIndex.indexOf(index) > -1) {if (startTime) {// 如果有开始时间,直接确定结束时间let endHour = Math.floor((index + 1) / 2);let endMin = (index + 1) % 2 === 0 ? "00" : "30";endTime = `${endHour < 10 ? '0' + endHour : endHour}:${endMin}`;} else {// 没有开始时间,确定当前点为开始时间let startHour = Math.floor(index / 2);let startMin = index % 2 === 0 ? "00" : "30";startTime = `${startHour < 10 ? '0' + startHour : startHour}:${startMin}`;}if (index === 2 * model.hours.length + 1) { // 如果是最后一格,直接结束endTime = `${Math.floor((index + 1) / 2)}:00`;model.timeRangeList.push(`${startTime ? startTime : "23:30"}-${endTime}`);startTime = '';endTime = '';}} else { // 若这个点不在选择区间,确定一个时间段if (startTime && endTime) {model.timeRangeList.push(`${startTime}-${endTime}`);startTime = '';endTime = '';} else if (startTime && !endTime) {// 这里可能只选半个小时let endHour = Math.floor(index / 2);let endMin = index % 2 === 0 ? "00" : "30";endTime = `${endHour < 10 ? '0' + endHour : endHour}:${endMin}`;model.timeRangeList.push(`${startTime}-${endTime}`);startTime = '';endTime = '';}}}model.tips = model.timeRangeList && model.timeRangeList.length > 0 ? model.timeRangeList : '';emit('data-passed', model.tips);
}// 点击事件
const handleClick = (index) => {if (model.selectStart) {if (index === model.startIndex) {// 双击取反if (model.timeRangeListIndex.indexOf(index) > -1) {model.timeRangeListIndex.splice(model.timeRangeListIndex.indexOf(index), 1);} else {model.timeRangeListIndex.push(model.startIndex);}} else if (index > model.startIndex) {// 选取数据--向右添加,向左取消while (index >= model.startIndex) {model.timeRangeListIndex.push(model.startIndex);model.startIndex = +model.startIndex + 1;}model.timeRangeListIndex = Array.from(new Set(model.timeRangeListIndex));} else {// 删除数据while (model.startIndex >= index) {if (model.timeRangeListIndex.indexOf(index) > -1) {model.timeRangeListIndex.splice(model.timeRangeListIndex.indexOf(index), 1);}index++;}}model.startIndex = '';transformedSection();model.tempRangeIndex = [];} else {model.startIndex = index;}model.selectStart = !model.selectStart;
}
// 预选区间
const handleHover = (index) => {if (model.selectStart) {model.tempRangeIndex = [];if (index > model.startIndex) {// 选取数据--向右添加,向左取消while (index >= model.startIndex) {model.tempRangeIndex.push(index);index--;}} else {// 删除数据while (model.startIndex >= index) {model.tempRangeIndex.push(index);index++;}}}
}
// 是否选中,计算className
const compClass = (index) => {if (index === model.startIndex) {return 'hours-item-left preSelected';}if (index >= model.startIndex) {if (model.tempRangeIndex.indexOf(index) > -1) {return 'hours-item-left preSelected';}} else {if (model.tempRangeIndex.indexOf(index) > -1) {return 'hours-item-left unSelected';}}return model.timeRangeListIndex.indexOf(index) > -1 ? 'hours-item-left selected' : 'hours-item-left';
}
</script><style lang="scss" scoped>
.hours-container {cursor: pointer;color: slategray;.hours-item-header-box {display: flex;width: 100%;height: 30px;.hours-item-header {width: 30px;height: 30px;text-align: center;box-sizing: border-box;line-height: 30px;border: 1px solid #5a5a5a;border-left: none;border-bottom: none;&:first-child {border-left: 1px solid #5a5a5a;}}}.hours-item-box {display: flex;width: 100%;.hours-item {width: 15px;height: 30px;border: 1px solid #474747;box-sizing: border-box;&.selected {background-color: #ffbf00 !important;border-bottom: 1px solid #c2d0f3;}&.preSelected {background-color: rgb(255, 191, 0);border-bottom: 1px solid #c2d0f3;}&.unSelected {background-color: #ffffff;border-bottom: 1px solid #c2d0f3;}}}
}.tips {width: 100%;line-height: 30px;margin-top: 10px;
}</style>

相关文章:

vue3+ts 实现时间间隔选择器

需求背景解决效果视频效果balancedTimeElement.vue 需求背景 实现一个分片的时间间隔选择器&#xff0c;需要把显示时间段显示成图表&#xff0c;涉及一下集中数据转换 [“02:30-05:30”,“07:30-10:30”,“14:30-17:30”]‘[(2,5),(7,10),(14,17)]’[4, 5, 6, 7, 8, 9, 10, …...

PTA 魔法优惠券

7-83 魔法优惠券 分数 25 全屏浏览题目 作者 陈越 单位 浙江大学 在火星上有个魔法商店&#xff0c;提供魔法优惠券。每个优惠劵上印有一个整数面值K&#xff0c;表示若你在购买某商品时使用这张优惠劵&#xff0c;可以得到K倍该商品价值的回报&#xff01;该商店还免费赠送…...

P8A110-A120经典赛题

Web应用程序SQL Inject安全攻防 任务环境说明&#xff1a; 服务器场景&#xff1a;WebServ2003&#xff08;用户名&#xff1a;administrator&#xff1b;密码&#xff1a;空&#xff09;服务器场景操作系统&#xff1a;Microsoft Windows2003 Server 服务器场景安装服务/工…...

文件基础知识

计算机中的流&#xff1a;在C语言中将通过输入/输出设备&#xff08;键盘、内存、显示器、网络等&#xff09;之间的数据传输抽象表述为“流”。 1、文本流和二进制流 在文本流中输入输出的数据是一系列的字符&#xff0c;可以被修改在二进制流中输入输出数据是一系列字节&am…...

二叉树OJ题之二

今天我们一起来看一道判断一棵树是否为对称二叉树的题&#xff0c;力扣101题&#xff0c; https://leetcode.cn/problems/symmetric-tree/ 我们首先先来分析这道题&#xff0c;要判断这道题是否对称&#xff0c;我们首先需要判断的是这颗树根节点的左右子树是否对称&#xff0…...

MySql表中添加emoji表情

共五处需要修改。 语句执行修改&#xff1a; ALTER TABLE xxxxx CONVERT TO CHARACTER SET utf8mb4;...

【新手解答1】深入探索 C 语言:变量名、形参 + 主调函数、被调函数 + 类和对象 + 源文件(.c 文件)、头文件(.h 文件)+ 库

C语言的相关问题解答 写在最前面目录 问题1变量名与变量的关系与区别变量和数据类型形参&#xff08;形式参数&#xff09;的概念 问题2解析&#xff1a;主调函数和被调函数延伸解析&#xff1a;主调函数对于多文件程序的理解总结 问题3类和对象变量和数据类型变量是否为抽象的…...

2023最新的软件测试热点面试题(答案+解析)

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…...

NCo3.1(08) - Nco3 服务器端编程

本篇博文不再重复ABAP调用外部服务器的基础&#xff0c;只介绍 NCo3 开发的过程和要点。需要了解相关知识点的小伙伴们自行参考&#xff1a; SAP接口编程 之JCo3.0系列(06) - Jco服务器端编程 PyRFC 服务器端编程要点 创建项目 新建一个 Console 项目&#xff0c;选择 .Net …...

【代码随想录】算法训练计划36

贪心 1、435. 无重叠区间 题目&#xff1a; 给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 思路&#xff1a; 贪心&#xff0c;重叠个数&#xff0c;和射气球一样,重叠区间…...

Python (十五) 面向对象之多继承问题

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…...

广域网加速技术

摘要&#xff1a; 随着企业数字化转型快速发展&#xff0c;越来越多企业将IT系统、应用和服务部署到云上&#xff0c;以实现更高效、灵活的管理和使用。这就对广域网提出了更高的要求&#xff0c;而广域网线路往往存在带宽费用昂贵、服务质量不可靠等问题。为了改善用户体验&am…...

构建智能医患沟通:陪诊小程序开发实战

在医疗科技的浪潮中&#xff0c;陪诊小程序的开发成为改善医患沟通的创新途径之一。本文将介绍如何使用Node.js和Express框架构建一个简单而强大的陪诊小程序&#xff0c;实现患者导诊和医生咨询功能。 1. 安装Node.js和Express 首先确保已安装Node.js&#xff0c;然后使用以…...

插入区间[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个无重叠的 &#xff0c;按照区间起始端点排序的区间列表。在列表中插入一个新的区间&#xff0c;你需要确保列表中的区间仍然有序且不重叠&#xff08;如果有必要的话&#xff0c;可以合并区间&#xff09;。 示例 1&#x…...

Android Bitmap 模糊效果实现 (二)

文章目录 Android Bitmap 模糊效果实现 (二)使用 Vukan 模糊使用 RenderEffect 模糊使用 GLSL 模糊RS、Vukan、RenderEffect、GLSL 效率对比 Android Bitmap 模糊效果实现 (二) 本文首发地址 https://blog.csdn.net/CSqingchen/article/details/134656140 最新更新地址 https:/…...

初识Java 18-4 泛型

目录 泛型存在的问题 在泛型中使用基本类型 实现参数化接口 类型转换和警告 无法实现的重载 基类会劫持接口 自限定类型 奇异递归类型 自限定 自限定提供的参数协变性 本笔记参考自&#xff1a; 《On Java 中文版》 泛型存在的问题 接下来讨论的&#xff0c;是在泛型…...

家政保洁预约小程序app开发特点有哪些?

家政预约服务小程序APP开发的特点介绍&#xff1b; 1. 低成本&#xff1a;用户通过手机APP下单&#xff0c;省去了中介费用&#xff0c;降低了雇主的雇佣成本。 2. 高收入&#xff1a;家政服务人员通过手机APP接单&#xff0c;省去了中介费用&#xff0c;从而提高了服务人员的…...

【JavaEE初阶】 HTTP响应报文

文章目录 &#x1f332;序言&#x1f38d;200 OK&#x1f340;404 Not Found&#x1f384;403 Forbidden&#x1f334;405 Method Not Allowed&#x1f38b;500 Internal Server Error&#x1f333;504 Gateway Timeout&#x1f332;302 Move temporarily&#x1f38d;301 Move…...

PTA: 螺旋矩阵

题目 所谓“螺旋矩阵”&#xff0c;是指对任意给定的N&#xff0c;将1到NN的数字从左上角第1个格子开始&#xff0c;按顺时针螺旋方向顺序填入NN的方阵里。本题要求构造这样的螺旋方阵。 格式 输入格式: 输入在一行中给出一个正整数N&#xff08;<10&#xff09;。 输出…...

SparkSQL远程调试(IDEA)

启动Intellij IDEA&#xff0c;打开spark源码项目&#xff0c;配置远程调试 Run->Edit Configuration 启动远程spark-sql spark-sql --verbose --driver-java-options "-Xdebug -Xrunjdwp:transportdt_socket,servery,suspendy,address5005"运行远程调试&#xf…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...