当前位置: 首页 > 知识库问答 >
问题:

javascript - 动态添加时间范围,如何置灰已选择时间?

闽涵蓄
2024-03-29

先说下需求:开始时段和结束时段是24小时按照30分钟分割成48个点的数据,数据格式如下:["00:00","00:30","01:00","01:30",.....,"23:30"],每行数据后都有新增和删除操作。

1、开始时段选择后,结束时段小于开始时段的值置灰不能选择。

2、假如:开始时段选择了 "01:00",结束时段选择了 "03:30",点击后边新增时,前边已选的数据置灰不能选择,第二条的数据选择只能在这个范围内:"00:00"-"01:00","03:30"-"23:30",
当用户开始时间选择了"00:00",则结束时间只能选择"00:00"到"01:00"范围内的任何一个值,其他时间段都置灰。
当用户开始时间选择了"03:30",则结束时间只能在"03:30"到"23:30"范围内的任何一个值,而"00:00"到"03:30"置灰不能选择。

3、当第二条数据选择了 "05:00",结束时间选择了"05:30",点击后边新增时,前边已选的数据置灰不能选择,第三条的数据选择只能在这个范围内:"00:00"-"01:00","03:30"-"05:00","05:30"-"23:00",
当用户开始时间选择了"00:00",则结束时间只能选择"00:00"到"01:00"范围内的任何一个值,其他时间段都置灰。
当用户开始时间选择了"03:30",则结束时间只能选择"03:30"到"05:00"范围内的任何一个值,其他时间段都置灰。
当用户开始时间选择了"05:30",则结束时间只能在"05:30"到"23:30"范围内的任何一个值,而"00:00"到"05:30"置灰不能选择。
以此类推...

4、当删除某行数据时,已删除的数据要重新进行可选和置灰操作。

页面如下:
初次进入页面显示:
image.png
添加一行数据显示:
image.png

以下是我的代码,各位大佬后边的逻辑如何实现?

html

<template>  <el-dialog    :visible.sync="showSetDialog.visible"    v-dialogDrag    width="620px"    :title="showSetDialog.title"    :close-on-click-modal="false"    :append-to-body="true"    @close="handleDialogClose"  >    <el-form ref="form" size="mini" label-width="90px" :inline="true">      <div v-for="(item, index) in allTimeData" :key="index">        <el-form-item prop="startTime">          <el-select            v-model="item.startTime"            placeholder="开始时段"            style="margin-right: 5px"            @change="handleStartChange"          >            <el-option              v-for="(list, index) in stList"              :key="index"              :value="list.value"              :label="list.label"              :disabled="list.disabled"            ></el-option> </el-select          >-        </el-form-item>        <el-form-item prop="endTime">          <el-select            v-model="item.endTime"            placeholder="结束时段"          >            <el-option              v-for="(list, index) in etList"              :key="index"              :value="list.value"              :label="list.label"              :disabled="list.disabled"            ></el-option>          </el-select>        </el-form-item>        <el-form-item>          <i            v-if="index == allTimeData.length - 1"            class="el-icon-circle-plus-outline plus-icon"            @click="handleElecPlus(item)"          ></i>          <i            v-if="allTimeData.length > 1"            class="el-icon-remove-outline remove-icon"            @click="handleElecRemove(index)"          ></i>        </el-form-item>      </div>    </el-form>    <div slot="footer" class="dialog-footer">      <el-button size="small" @click="handleDialogClose">取 消</el-button>      <el-button size="small" type="primary" @click="handleDialogSave">        确 定      </el-button>    </div>  </el-dialog></template>

js

<script>export default {   data(){     return {       newItem: {        startTime: "",        endTime: "",      },      allTimeData: [        {          startTime: "",          endTime: "",        },      ],    timeOptions: [    "00:00",    "00:30",    "01:00",    "01:30",    "02:00",    "02:30",    "03:00",    "03:30",    "04:00",    "04:30",    "05:00",    "05:30",    "06:00",    "06:30",    "07:00",    "07:30",    "08:00",    "08:30",    "09:00",    "09:30",    "10:00",    "10:30",    "11:00",    "11:30",    "12:00",    "12:30",    "13:00",    "13:30",    "14:00",    "14:30",    "15:00",    "15:30",    "16:00",    "16:30",    "17:00",    "17:30",    "18:00",    "18:30",    "19:00",    "19:30",    "20:00",    "20:30",    "21:00",    "21:30",    "22:00",    "22:30",    "23:00",    "23:30"]     }   },  props: {    showSetDialog: {      type: Object,      default: () => ({}),    },  },computed: {   // 获取起始时刻的数据    stList() {      return this.timeOptions.map((item) => ({        value: item,        label: item,        disabled: false,      }));   // 获取结束时间的数据   etList() {      return this.timeOptions.map((item) => ({        value: item,        label: item,        disabled: false,     }));    },},methods: {   // 新增    handleElecPlus(item) {      if (item.startTime && item.endTime) {        this.allTimeData.push(this.newItem);      } else {        this.$message.warning("开始时间和结束时间不能为空");        return false;      }    },    // 删除当前行    handleElecRemove(index) {      this.allTimeData.splice(index, 1);    },    // 触发开始时间下拉框事件    handleStartChange() {},}}</script>

共有2个答案

轩辕源
2024-03-29

我觉得你可以动态生成 timeOptions
你可以用一个计算属性调用 generatorTimeOptions ,根据已选的数据传入适当的 skipList 这样你就不用关心 删除 新增这些逻辑了。

/** * 生成时间选项 * * @param startTime 开始时间,单位为分钟,默认为0 * @param endTime 结束时间,单位为分钟,默认为1440 * @param step 步长,单位为分钟,默认为30 * @param skipList 需要跳过的时间段列表,格式为[['00:00', '01:00'], '02:00'],默认为空数组 * @returns 返回时间选项数组,格式为['00:00', '00:30', ...] */export function generatorTimeOptions(startTime = 0, endTime = 1440, step = 30, skipList = []) {  let currentTime = startTime  const options = []  let skipMinutes = []  if (skipList && skipList.length > 0) {    skipMinutes = skipList.map((item) => {      if (Array.isArray(item) && item.length === 2) {        return {          start: timeToMinutes(item[0]),          end: timeToMinutes(item[1]),        }      } else if (Array.isArray(item) && item.length === 1) {        return {          start: timeToMinutes('00:00'),          end: timeToMinutes(item[0]),        }      } else if (item && item.split(':').length === 2) {        return {          start: timeToMinutes('00:00'),          end: timeToMinutes(item),        }      }    })  }  while (currentTime < endTime) {    let skip = false    if (skipMinutes.length > 0) {      skipMinutes.forEach((item) => {        if (currentTime >= item.start && currentTime <= item.end) {          skip = true        }      })    }    if (!skip) {      options.push(minutesToTime(currentTime))    }    currentTime += step  }  return options}function timeToMinutes(time = '00:00') {  return time.split(':').reduce((total, cur, index) => {    if (index === 0) {      total += Number(cur) * 60    } else {      total += Number(cur)    }    return total  }, 0)}function minutesToTime(minutes = 0) {  let hour = Math.floor(minutes / 60)  let minute = minutes % 60  if (minute < 10) {    minute = `0${minute}`  }  if (hour < 10) {    hour = `0${hour}`  }  return `${hour}:${minute}`}

上面的代码你可以存为一个文件
然后在你的代码里

import {generatorTimeOptions} from '文件位置'// ...computed: {   timeOptions() {      const skipList = this.allTimeData.map(item => {         return item.startTime && item.endTime ? {            start: item.startTime,            end: item.endTime,         } : item.startTime      })      return generatorTimeOptions(0, 1440, 30, skipList);   }
鲁乐
2024-03-29

试试这个

// 计算结束时间是否应被禁用isDisabledEndTime(timeOption, dataIndex) {  if (dataIndex === 0) {    // 第一行的结束时间不受限制    return false;  }  const previousEnd = this.allTimeData[dataIndex - 1].endTime;  // 当前选择的开始时间  const currentStart = this.allTimeData[dataIndex].startTime;  // 遍历已占用的时间区间,找到与当前开始时间相邻的占用区间  const occupiedInterval = this.occupiedIntervals.find(    interval => currentStart >= interval[0] && currentStart <= interval[1]  );  if (occupiedInterval) {    // 如果找到与当前开始时间相邻的占用区间,则禁用在该区间内的结束时间    return timeOption >= occupiedInterval[0] && timeOption <= occupiedInterval[1];  } else {    // 在没有找到相邻占用区间的情况下,仅当结束时间小于等于前一行结束时间时禁用    return timeOption <= previousEnd;  }},
// 更新禁用状态的方法updateOccupiedIntervals() {  this.occupiedIntervals = [];  for (let i = 0; i < this.allTimeData.length; i++) {    const start = this.timeOptions.indexOf(this.allTimeData[i].startTime);    const end = this.timeOptions.indexOf(this.allTimeData[i].endTime);    // 将每个有效时间段添加到占用区间列表,但排除与前一时间段相连的情况    if (i === 0 || start > this.occupiedIntervals[this.occupiedIntervals.length - 1][1]) {      this.occupiedIntervals.push([start, end]);    } else {      this.occupiedIntervals[this.occupiedIntervals.length - 1][1] = Math.max(this.occupiedIntervals[this.occupiedIntervals.length - 1][1], end);    }  }},
 类似资料:
  • 如何动态计算时间所处的范围? 有如下场景,计算某一天的差旅补贴时(不考虑跨天),要根据出发时间t1和到达时间t2判断补贴的金额,同时出发时间的判断标准和返回时间的判断标准现在为12时(24小时制)。 现在有如下规则: t1>=(出发时间判断标准)12点,补贴为0.5,不考虑t2; t1<(出发时间判断标准)12点: t2>12(返回时间判断标准),补贴为1; t2<=12(返回时间判断标准),补贴

  • 问题内容: T-SQL DateTime问题。 我有一组时间范围。在这些时间范围内,可能会有一组重叠的时间范围,我称之为“封锁”时间。封锁的时间不会超过一天。我想要做的是分配时间以排除阻塞时间,基本上是给我没有“阻塞”的时间范围。可以肯定的是,阻塞时间不能超出时间范围。 示例:我工作时间是从上午9点到下午5点,在下午1点有30分钟的午餐时间。我想要2行的结果:9am至1pm和1.30pm至5pm。

  • 问题内容: 如何在MySQL中的日期范围之间选择数据。我的专栏是24小时的祖鲁时间格式。 尽管在这些时间段之间有数据,但不返回任何内容。我是否必须强制 “发件人” 和 “发件人” 字段中的值键入查询? 问题答案: 您需要更新日期格式:

  • 本文向大家介绍extjs 时间范围选择自动判断的实现代码,包括了extjs 时间范围选择自动判断的实现代码的使用技巧和注意事项,需要的朋友参考一下 extjs中 有时需要选择一个日期范围,需要自动判断,选择的开始日期不能大于结束日期,或结束日期不能小于开始日期,实现的代码如下 效果图: 从上图可以看到,当选择了一个开始时间后,会自动限制结束时间的选择范围,实现两个日期选择器的联动. 代码如下: 首

  • 问题内容: 我有两个String变量- 和。两者都包含格式为 HH:MM的值 。我该如何检查: 如果当前的时间内 和 会在最近一小时发生吗? 更新。 我实现了以下内容以转换为格式。但是它使用折旧方法: 问题答案: 将两个字符串转换为 对象(也是时间对象)创建一个新对象。 这将包含当前时间。 使用Date.before()和Date.after()方法来确定您是否在时间间隔内。 编辑:您应该能够直接

  • 问题内容: 目前,我的表格中有一列存储日期和时间。该列的数据类型是 没有时区的时间戳 。因此它具有格式为的值。 我需要检索有关日期的行。如果我使用: 它将提供介于“ 2011-09-13 11:03:44.537”和“ 2011-09-12 11:03:44.537”之间的值。 但是,如果我要使用: 没有日期,月份和秒,它不显示任何行。 如何从此表中获取有关日期的值(仅包含日期,忽略小时,分钟和秒