js对已选数据进行范围过滤
项目场景:类型包含全年和季节,季节是可以配置的,不管选择年还是季节,都可以新增需求响应数据,弹窗中有两个下拉框,起始时刻和终止时刻,范围是0-23,选择一条信息填写完可以点击保存,点击页面中新增可以打开弹窗重新增加信息遇到问题: 第一次添加数据:如果起始时间选择3,终止时间选择6进行保存,下次新增时3-6是不能选择,而且新选择的时间范围不能包含3-6,比如新选择的起始时间是1,终止时间是9,因为1-9包含了3-6的部分,所以不能选择,但是0-3可以选择,7-10可以选择。 第二次添加数据:如果起始时间选择9,终止时间选择14进行保存,这时新增的全部数据是:
hasAddData = [
{startTime: 3, endTime: 6, upValue: 1,downValue: 0.3},
{startTime: 9, endTime: 14, upValue: 0.5,downValue: 0.8},
]
下次新增时,只能选择的数据列表为: [0,1,2],[7,8],[15,16,17,18,19,20,21,22,23],如果起始时刻选择0,终止时刻只能是0、1或者2,如果起始时刻选择是7,终止时刻只能是8。 以此类推,写出起始时刻的下拉框数据和终止时刻的下拉框数据。弹窗图示:
以下是实现逻辑:
<template>
<div class="addTime">
<el-dialog
title="新增需求响应时段"
:visible.sync="showAddDialog.visible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:modal-append-to-body="false"
:append-to-body="true"
width="450px"
top="20vh"
v-loading="formLoading"
>
<el-form
size="mini"
label-position="left"
label-width="140px"
:model="timeInfoForm"
:rules="timeRules"
ref="timeInfoForm"
>
<el-form-item
label="季节"
prop="season"
v-if="showAddDialog.type === 2"
>
<el-select
v-model="timeInfoForm.season"
placeholder="请选择季节"
style="width: 245px"
@change="handleSeasonChange"
>
<el-option
v-for="item in seasonList"
:key="item"
:label="item"
:value="item"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="起始时刻" prop="st">
<el-select
v-model="timeInfoForm.st"
placeholder="请选择起始时刻"
style="width: 245px; margin-right: 5px"
@change="handleStartChange"
>
<el-option
v-for="item in stList"
:key="item"
:label="item"
:value="item"
></el-option> </el-select
>时
</el-form-item>
<el-form-item label="终止时刻" prop="et">
<el-select
v-model="timeInfoForm.et"
placeholder="请选择终止时刻"
style="width: 245px; margin-right: 5px"
>
<el-option
v-for="item in etList"
:key="item"
:label="item"
:value="item"
></el-option> </el-select
>时
</el-form-item>
<el-form-item label="可上调电负荷比例" prop="up">
<el-input
v-model.trim="timeInfoForm.up"
placeholder="0-1之间"
clearable
style="width: 245px"
>
</el-input>
</el-form-item>
<el-form-item label="可下调电负荷比例" prop="down">
<el-input
v-model.trim="timeInfoForm.down"
placeholder="0-1之间"
clearable
style="width: 245px"
>
</el-input>
</el-form-item>
</el-form>
<div slot="footer">
<el-button type="reset" @click="handleFormCancel" size="small"
>取 消</el-button
>
<el-button type="primary" @click="handleFormSubmit" size="small"
>保 存</el-button
>
</div>
</el-dialog>
</div>
</template>
export default {
name: "addTime",
props: {
showAddDialog: {
type: Object,
default: () => {},
},
},
data() {
return {
formLoading: false,
timeInfoForm: {
season: "",
st: "",
et: "",
up: "",
down: "",
},
seasonList: [],
hasAddData: [], // 已添加数据
};
},
created() {
// data是父组件传递过来已经添加的数据
let data = this.$deepClone(this.showAddDialog.data);
// type---> 1年,2季节
if (this.showAddDialog.type == 2) {
// columns是父组件传递过来的季节数据
this.seasonList = this.showAddDialog.columns;
this.timeInfoForm.season = this.seasonList[0];
this.handleDataFormat();
} else {
this.hasAddData = data;
}
},
computed: {
// 获取默认的0-23小时数据
getAllTimeData() {
let arr = [];
for (let i = 0; i <= 23; i++) {
arr.push(i);
}
return arr;
},
// 获取起始时刻的数据
stList() {
return this.getAllTimeData.filter((t) =>
this.hasAddData.every(({ st, et }) => t < st || t > et)
);
},
// 获取终止时刻的数据
etList() {
let start = this.timeInfoForm.st;
let startIndex = this.stList.indexOf(start);
return this.stList.filter(
(t, i) => t >= start && t - start === i - startIndex
);
},
},
methods: {
// 切换起始时间
handleStartChange() {
this.timeInfoForm.et = "";
},
// 季节格式化数据
handleDataFormat() {
let data = this.$deepClone(this.showAddDialog.data);
// 使用reduce函数,将数据分组
/**
let arr = {
春季: [
{season: "春季", st: 12, et: 15, up: 0.2, down: 0.4}
{season: "春季", st: 18, et: 21, up: 1, down: 1}
],
夏季: [
{season: "夏季", st: 12, et: 15, up: 0.2, down: 0.4}
],
秋季: [],
冬季: []
}
*/
let arr = data.reduce((prev, curr) => {
let key = curr["season"];
if (!prev[key]) {
prev[key] = [];
}
prev[key].push(curr);
return prev;
}, {});
// 如果该季节下没有数据,则使用默认的0-23小时数据
if (!arr[this.timeInfoForm.season]) {
this.hasAddData = [];
} else {
this.hasAddData = arr[this.timeInfoForm.season];
}
},
// 切换季节
handleSeasonChange(val) {
this.timeInfoForm.season = val;
this.handleDataFormat();
},
},
};
主要逻辑是计算出起始时刻和终止时刻,脑子中有一些想法,但是代码总是编写有问题,因此记录下大佬的编码,再次感谢边城大佬的帮助。
转载自:https://segmentfault.com/a/1190000042077134