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 需求背景 实现一个分片的时间间隔选择器,需要把显示时间段显示成图表,涉及一下集中数据转换 [“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 全屏浏览题目 作者 陈越 单位 浙江大学 在火星上有个魔法商店,提供魔法优惠券。每个优惠劵上印有一个整数面值K,表示若你在购买某商品时使用这张优惠劵,可以得到K倍该商品价值的回报!该商店还免费赠送…...
P8A110-A120经典赛题
Web应用程序SQL Inject安全攻防 任务环境说明: 服务器场景:WebServ2003(用户名:administrator;密码:空)服务器场景操作系统:Microsoft Windows2003 Server 服务器场景安装服务/工…...
文件基础知识
计算机中的流:在C语言中将通过输入/输出设备(键盘、内存、显示器、网络等)之间的数据传输抽象表述为“流”。 1、文本流和二进制流 在文本流中输入输出的数据是一系列的字符,可以被修改在二进制流中输入输出数据是一系列字节&am…...
二叉树OJ题之二
今天我们一起来看一道判断一棵树是否为对称二叉树的题,力扣101题, https://leetcode.cn/problems/symmetric-tree/ 我们首先先来分析这道题,要判断这道题是否对称,我们首先需要判断的是这颗树根节点的左右子树是否对称࿰…...
MySql表中添加emoji表情
共五处需要修改。 语句执行修改: ALTER TABLE xxxxx CONVERT TO CHARACTER SET utf8mb4;...
【新手解答1】深入探索 C 语言:变量名、形参 + 主调函数、被调函数 + 类和对象 + 源文件(.c 文件)、头文件(.h 文件)+ 库
C语言的相关问题解答 写在最前面目录 问题1变量名与变量的关系与区别变量和数据类型形参(形式参数)的概念 问题2解析:主调函数和被调函数延伸解析:主调函数对于多文件程序的理解总结 问题3类和对象变量和数据类型变量是否为抽象的…...
2023最新的软件测试热点面试题(答案+解析)
📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢交流讨论:欢迎加入我们一起学习!📢资源分享:耗时200小时精选的「软件测试」资…...
NCo3.1(08) - Nco3 服务器端编程
本篇博文不再重复ABAP调用外部服务器的基础,只介绍 NCo3 开发的过程和要点。需要了解相关知识点的小伙伴们自行参考: SAP接口编程 之JCo3.0系列(06) - Jco服务器端编程 PyRFC 服务器端编程要点 创建项目 新建一个 Console 项目,选择 .Net …...
【代码随想录】算法训练计划36
贪心 1、435. 无重叠区间 题目: 给定一个区间的集合 intervals ,其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。 思路: 贪心,重叠个数,和射气球一样,重叠区间…...
Python (十五) 面向对象之多继承问题
程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&…...
广域网加速技术
摘要: 随着企业数字化转型快速发展,越来越多企业将IT系统、应用和服务部署到云上,以实现更高效、灵活的管理和使用。这就对广域网提出了更高的要求,而广域网线路往往存在带宽费用昂贵、服务质量不可靠等问题。为了改善用户体验&am…...
构建智能医患沟通:陪诊小程序开发实战
在医疗科技的浪潮中,陪诊小程序的开发成为改善医患沟通的创新途径之一。本文将介绍如何使用Node.js和Express框架构建一个简单而强大的陪诊小程序,实现患者导诊和医生咨询功能。 1. 安装Node.js和Express 首先确保已安装Node.js,然后使用以…...
插入区间[中等]
优质博文:IT-BLOG-CN 一、题目 给你一个无重叠的 ,按照区间起始端点排序的区间列表。在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 示例 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 泛型
目录 泛型存在的问题 在泛型中使用基本类型 实现参数化接口 类型转换和警告 无法实现的重载 基类会劫持接口 自限定类型 奇异递归类型 自限定 自限定提供的参数协变性 本笔记参考自: 《On Java 中文版》 泛型存在的问题 接下来讨论的,是在泛型…...
家政保洁预约小程序app开发特点有哪些?
家政预约服务小程序APP开发的特点介绍; 1. 低成本:用户通过手机APP下单,省去了中介费用,降低了雇主的雇佣成本。 2. 高收入:家政服务人员通过手机APP接单,省去了中介费用,从而提高了服务人员的…...
【JavaEE初阶】 HTTP响应报文
文章目录 🌲序言🎍200 OK🍀404 Not Found🎄403 Forbidden🌴405 Method Not Allowed🎋500 Internal Server Error🌳504 Gateway Timeout🌲302 Move temporarily🎍301 Move…...
PTA: 螺旋矩阵
题目 所谓“螺旋矩阵”,是指对任意给定的N,将1到NN的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入NN的方阵里。本题要求构造这样的螺旋方阵。 格式 输入格式: 输入在一行中给出一个正整数N(<10)。 输出…...
SparkSQL远程调试(IDEA)
启动Intellij IDEA,打开spark源码项目,配置远程调试 Run->Edit Configuration 启动远程spark-sql spark-sql --verbose --driver-java-options "-Xdebug -Xrunjdwp:transportdt_socket,servery,suspendy,address5005"运行远程调试…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...
