VUE时间范围选择的组件

article/2025/9/21 5:00:10

最近手写了一个框选时间的组件,可以按半个小时为单位选择时间

 

代码部分

<template><div><div class="byted-schedule"><table :key="itemKey" class="byted-schedule-calendar-table"><thead><tr><th rowspan="8" class="byted-schedule-week-td">星期/事件</th><th colspan="24">00:00 - 12:00</th><th colspan="24">12:00 - 24:00</th></tr><tr><td v-for="index of 24" :key="index" colspan="2">{{ index - 1 }}</td></tr></thead><tbody @mouseleave="handelMouseLeave"><div v-show="is_show_mask" class="mask" :style="'width:' + mask_width + 'left:' + mask_left + 'height:' + mask_height + 'top:' + mask_top" /><tr v-for="(item, weekIndex) in week" :key="item"><td @mouseenter="handelMouseEnter">{{ item }}</td><tdv-for="timeIndex of timeLength":ref="`td${weekIndex * timeLength + timeIndex - 1}`":key="timeIndex":colspan="48 / timeLength":data-week="weekIndex":data-time="timeIndex":class="timeArray[weekIndex * timeLength + timeIndex - 1] === '1'? 'selected': ''"class="byted-schedule-calendar-atom-time"@mousedown="handelMouseDown(weekIndex, timeIndex - 1,$event)"@mousemove="handelMouseMove(weekIndex, timeIndex - 1,$event)"@mouseup="handelMouseUp(weekIndex, timeIndex - 1,$event)"/></tr><tr @mouseenter="handelMouseEnter"><td colspan="49"><div style="display: flex; justify-content: space-between"><span style="margin-left: 10px">已选择时间段</span><a:underline="false"style="margin-right: 10px;color: #1890FF;cursor:pointer"@click="clearAllTime">清空</a></div><div style="text-align: start; padding: 0 10px"><p v-for="(item, key) in timeObject" :key="key"><span v-if="item.length" style="margin-right: 10px">{{key}}</span><span v-if="item.length">{{ item.join("、") }}</span></p></div></td></tr></tbody></table></div></div></template><script>export default {name:'time-choice-range',props: {value: {type: String,default: ''},timeWidth: {type: Number,default: 7},timeLength: {type: Number,default: 48}},data() {return {is_show_mask: false,startWeekIndex: null,startTimeIndex: null,endWeekIndex: null,endTimeIndex: null,week: ['星期一','星期二','星期三','星期四','星期五','星期六','星期日'],cellStyle: {// color: 'red'},timeArray: [],itemKey: '',timeObject: {星期一: [],星期二: [],星期三: [],星期四: [],星期五: [],星期六: [],星期日: []},box_screen_left: 0, // 定位td的left位置box_screen_top: 0, // 定位td的top位置start_x: 0,start_y: 0,end_x: 0,end_y: 0}},created() {if (this.value) {this.timeArray = this.value.split('')for (var weekIndex = 0; weekIndex < this.timeWidth; weekIndex++) {this.handelClick(weekIndex)}} else {this.timeArray = []for (var i = 0; i < this.timeWidth * this.timeLength; i++) {this.timeArray[i] = '0'}}},computed: {mask_width() {return `${Math.abs(this.end_x - this.start_x)}px;`},mask_height() {return `${Math.abs(this.end_y - this.start_y)}px;`},mask_left() {return `${Math.min(this.start_x, this.end_x) - this.box_screen_left}px;`},mask_top() {return `${Math.min(this.start_y, this.end_y) - this.box_screen_top}px;`}},mounted() {window.addEventListener('scroll', this.handleScroll)},methods: {handleScroll() {const dom_box = document.querySelector('.byted-schedule-calendar-atom-time')this.box_screen_left = dom_box.getBoundingClientRect().left - 76this.box_screen_top = dom_box.getBoundingClientRect().top},handelClick(weekIndex, timeIndex) {var rowStartIndex = weekIndex * this.timeLengthvar i = 0var startAndEndTimeList = [] // 记录开始和结束时间while (i < this.timeLength) {if (this.timeArray[rowStartIndex + i] === '1') {var item = {startTime: null,endTime: null}item.startTime = i * (24 / this.timeLength)var obj = this.findEndTime(weekIndex, i)i = obj.indexitem.endTime = obj.endTimestartAndEndTimeList.push(item)}i++}var checkedTimeList = []for (let k = 0; k < startAndEndTimeList.length; k++) {var start = this.numToTime(startAndEndTimeList[k].startTime)var end = this.numToTime(startAndEndTimeList[k].endTime)var str = start + '~' + endcheckedTimeList.push(str)}this.timeObject[this.week[weekIndex]] = JSON.parse(JSON.stringify(checkedTimeList))},findEndTime(weekIndex, timeIndex) {var index = weekIndex * this.timeLength + timeIndexvar obj = {}obj.index = timeIndexif (this.timeArray[index] === '0') {obj.endTime = timeIndex * (24 / this.timeLength)return obj}// 如果选择了当天最后时段if (timeIndex === this.timeLength - 1 && this.timeArray[index] === '1') {obj.endTime = this.timeLength * (24 / this.timeLength)return obj}return this.findEndTime(weekIndex, timeIndex + 1)},numToTime(num) {var hour = parseInt(num)var minute = num % 1hour = hour < 10 ? '0' + hour : hour + ''minute = minute === 0 ? '00' : minute * 60 + ''return hour + ':' + minute},findStartAndEndTime(weekIndex, timeIndex) {var startXvar startYvar endXvar endYstartX =this.startWeekIndex < weekIndex ? this.startWeekIndex : weekIndexstartY =this.startTimeIndex < timeIndex ? this.startTimeIndex : timeIndexendX = this.startWeekIndex < weekIndex ? weekIndex : this.startWeekIndexendY = this.startTimeIndex < timeIndex ? timeIndex : this.startTimeIndexreturn {startX,startY,endX,endY}},handelMouseDown(weekIndex, timeIndex, event) {this.handleScroll()// 获取一下组件在视窗的位置this.startWeekIndex = weekIndexthis.startTimeIndex = timeIndex// 选择框this.is_show_mask = truethis.start_x = event.clientXthis.start_y = event.clientYthis.end_x = event.clientXthis.end_y = event.clientY},handelMouseMove(weekIndex, timeIndex, event) {this.endWeekIndex = weekIndexthis.endTimeIndex = timeIndexif (this.startWeekIndex !== null) {// event.path[0].style.background='#7594ef'const { startX, endX, startY, endY } = this.findStartAndEndTime(weekIndex,timeIndex)for (var i = startX; i <= endX; i++) {for (var j = startY; j <= endY; j++) {this.$refs[`td${i * this.timeLength + j}`][0].style.background ='#7594ef'}}}this.end_x = event.clientXthis.end_y = event.clientY},handelMouseLeave(event) {if (this.startWeekIndex !== null) {this.handelMouseUp(this.endWeekIndex, this.endTimeIndex)}},handelMouseEnter(event) {if (this.startWeekIndex !== null) {this.handelMouseUp(this.endWeekIndex, this.endTimeIndex)}},handelMouseUp(weekIndex, timeIndex) {if (this.startWeekIndex !== null) {const { startX, endX, startY, endY } = this.findStartAndEndTime(weekIndex,timeIndex)var value =this.timeArray[this.startWeekIndex * this.timeLength + this.startTimeIndex]for (var i = startX; i <= endX; i++) {for (var j = startY; j <= endY; j++) {this.timeArray[i * this.timeLength + j] = value === '1' ? '0' : '1'this.itemKey = Math.random()this.handelClick(i, j)}}}this.startWeekIndex = nullthis.startTimeIndex = nullthis.endWeekIndex = nullthis.endTimeIndex = nullthis.$emit('input', this.timeArray.join(''))this.is_show_mask = falsethis.resSetXY()},resSetXY() {this.start_x = 0this.start_y = 0this.end_x = 0this.end_y = 0},clearAllTime() {for (var i = 0; i < this.timeWidth * this.timeLength; i++) {this.timeArray[i] = '0'}this.timeObject = {星期一: [],星期二: [],星期三: [],星期四: [],星期五: [],星期六: [],星期日: []}this.$emit('input', '')}}}</script><style scoped src="../assets/index.css"></style>

css

.byted-schedule {user-select: none;}.byted-schedule table {border: 1px solid #ebebeb;border-collapse: collapse;table-layout: fixed;width: 100%;font-size: 12px;}.byted-schedule-calendar-table {border-collapse: separate;border-radius: 4px;}.byted-schedule-calendar-table tr td,.byted-schedule-calendar-table tr th {border-left: none;border-top: none;border-bottom: 1px solid;border-bottom-color: #ebebeb;border-right: 1px solid;border-right-color: #ebebeb;font-size: 14px;text-align: center;min-width: 11px;line-height: 1.8em;/* transition: background 200ms ease; */color: #333333;background: transparent;padding: 0;}.byted-schedule-week-td {width: 75px;padding: 20px 0;}.byted-schedule-calendar-table .selected {background: #1890ff !important;}.byted-schedule-calendar-atom-time:hover {background: #edf1fd;}tbody{position: relative;overflow: hidden;}.mask {position: absolute;background: red;opacity: 0.4;z-index: 999;}

npm

1、npm install time-choice-range

2、main.js:引入import time-choice-range from 'time-choice-range'

Vue.use(time-choice-range)

3.    <time-choice-range></time-choice-range>


http://chatgpt.dhexx.cn/article/oFEBwqsu.shtml

相关文章

Mysql获取指定时间范围数据

MySQL获取某个时间范围内的数据 TO_DAYS(date)函数。 to_days()&#xff1a;返回从0000年至当前日期的总天数。 目录 1、今天(TO_DAYS()) 2、今天昨天(TO_DAYS()) 3.近7天(DATE_SUB()) 5.本月(DATE_FORMAT()) 6.上一月(PERIOD_DIFF()) 7.本季度 8.上季度 9.本年 ​1…

Mybatis-Plus时间范围查询

方式一 通过apply方法&#xff0c;来实现时间范围查询&#xff0c;该方法可用于数据库函数&#xff0c;动态入参的params对应前面applySql内部的{index}部分&#xff0c;这样是不会有sql注入风险的&#xff0c;反之会有! apply(String applySql, Object... params) apply(boo…

elementui DateTimePicker组件 限制时间范围(包含时分秒)

1、基础范围控制&#xff08;只控制日期&#xff0c;不含时分秒&#xff09; <template><el-date-pickertype"datetime"v-model"startDate"value-format"yyyy-MM-dd HH:mm:ss"placeholder"选择开始时间"size"mini"…

MongoDB查询某个时间范围

MongoDB 时间范围查询目前有两种方式&#xff1a; DateISODate MongoDB条件对应关系 (>) 大于 - $gt(<) 小于 - $lt(>) 大于等于 - $gte(< ) 小于等于 - $lte Date方式 例如查询时间段为2023.01.03<日期<2023.01.05可翻译为&#xff1a; "日期字段名&…

移动端时间范围选择

div模块 <div className"choseDate"><div className"range"><input classNamestartTime onClick{()>{this.setState({startVisible:true})}} placeholder"请选择开始日期" value{this.state.startTime} /><DatePickert…

sql查询时间范围数据

mapper.xml >查询一定时间范围 条件:年月日 时分秒 <if test"creatAt ! null and creatAt ! "><![CDATA[and DATE_FORMAT(ride_order.created_at, %Y-%m-%d %h-%m-%s)> DATE_FORMAT(#{creatAt}, %Y-%m-%d %h-%m-%s) ]]></if><if test&qu…

JAVA判断当前时间在时间范围内

我们在日常开发的时候肯定有围绕时间选择的一些功能, 今天给大家分享一个java如何判断当前时间是否在所选择时间范围内的一个小demo public static void main(String[] args) throws ParseException {SimpleDateFormat ft new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss&q…

JavaScript 时间范围

当前时间往前的时间范围&#xff08;六个月之前&#xff09; 效果图 js文件代码片 /*查询日期区间&#xff08;当前时间往前&#xff09; Add By Vivian 2020/12/04 */ //rangeVal:两个日期的间隔符 num&#xff1a;隔多少 timeType&#xff1a;相隔时间类型 function funGet…

JavaScript如何判定一个给定的时间区间在哪些时间段范围内?

作者 | 十方 来源 | https://segmentfault.com/a/1190000041958661 有这样的一个场景&#xff1a;给定一个时间区间&#xff0c;需要判定这个时间区间在哪些时间段范围内. 比如时间段范围如下&#xff1a; [["00:00","01:00"],["01:00","02…

Impala-shell命令参数

文章目录 1. impala-shell外部命令2. impala-shell内部命令 1. impala-shell外部命令 所谓的外部命令指的是不需要进入到impala-shell交互命令行当中即可执行的命令参数。impala-shell后面执行的时候可以带很多参数。你可以在启动 impala-shell 时设置&#xff0c;用于修改命令…

Impala和Hive的关系(详解)

Impala和Hive的关系 Impala是基于Hive的大数据实时分析查询引擎&#xff0c;直接使用Hive的元数据库Metadata,意味着impala元数据都存储在Hive的metastore中。并且impala兼容Hive的sql解析&#xff0c;实现了Hive的SQL语义的子集&#xff0c;功能还在不断的完善中。 Hive hi…

impala理论篇之三:impala介绍

简介 Impala是Cloudera公司主导开发的新型查询系统&#xff0c;是Google Dremel的开源实现。它提供SQL语义&#xff0c;能够查询存储在Hadoop的HDFS和HBase中的PB级大数据。已有的Hive系统虽然也提供了SQL语义&#xff0c;但是由于Hive底层执行使用的是MapReduce引擎&#xff…

Impala优化

作为铺垫&#xff0c;本文首先对Broadcast Join和Partitioned Join进行简要介绍。 Broadcast Join 顾名思义&#xff0c;Broadcast Join就是广播的方式进行Join。以下图为例&#xff0c;假设Join操作为SELECT A JOIN B ON A.idB.id&#xff0c;Broadcast Join就是将B表&#…

impala与hive的比较以及impala的有缺点

最近读的几篇关于impala的文章&#xff0c;这篇良心不错&#xff1a;https://www.biaodianfu.com/impala.html&#xff08;本文截取部分内容&#xff09; Impala是Cloudera公司主导开发的新型查询系统&#xff0c;它提供SQL语义&#xff0c;能查询存储在Hadoop的HDFS和HBase中的…

impala命令

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 impala 前言一、impala是什么 &#xff1f;二、使用步骤1.数据拼接2.exists()cast()regexp_like()nvl() 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1…

Apache Impala(1):Impala简介

1 Impala 基本介绍 impala 是 cloudera 提供的一款高效率的 sql 查询工具&#xff0c;提供实时的查询效果&#xff0c;官方测试性能比 hive 快 10 到 100 倍&#xff0c;其 sql 查询比 sparkSQL 还要更加快速&#xff0c;号称是当前大数据领域最快的查询 sql 工具&#xff0c…

大数据Impala系列之初识Impala

一、impala 概述 1、什么是Impala&#xff1f; Impala是用于处理存储在Hadoop集群中的大量数据的MPP&#xff08;大规模并行处理&#xff09;SQL查询引擎。 它是一个用C 和Java编写的开源软件。 与其他Hadoop的SQL引擎相比&#xff0c;它提供了高性能和低延迟。 2、为什么选…

Impala 安装部署

文章目录 1. 安装前提2. 下载安装包&#xff0c;依赖包3. 虚拟机新增磁盘 &#xff08;磁盘空间有余则跳过此步骤&#xff09;3.1 关机新增磁盘3.2 开机挂载磁盘 4. 配置本地 yum 源4.1 上传安装包解压4.2 配置本地yum源信息 5. 安装Impala5.1 集群规划5.2 主节点安装5.3 从节点…

Apache Impala : Impala安装部署

Impala Impala安装部署安装前提下载安装包、依赖包虚拟机新增磁盘&#xff08;可选&#xff09;关机新增磁盘开机挂载磁盘 配置本地yum源上传安装包解压配置本地yum源信息 安装Impala集群规划主节点安装从节点安装 修改Hadoop、Hive配置修改hive配置修改hadoop配置复制hadoop、…

Impala的使用

Impala的核心开发语言是sql语句&#xff0c;Impala有shell命令行窗口&#xff0c;以及JDBC等方式来接收sql语句执行&#xff0c; 对于复杂类型分析可以使用C或者Java来编写UDF函数。 Impala的sql语法是高度集成了Apache Hive的sql语法&#xff0c;Impala支持Hive支持的数据类型…