乐趣区

关于vue.js:js对已选数据进行范围过滤

记录一次 @边城大佬 帮我解决的难题。感激大佬,以下是大佬的主页,大家能够关注下。
https://segmentfault.com/u/ja…


我的项目场景:类型蕴含全年和节令,节令是能够配置的,不论抉择年还是节令,都能够新增需要响应数据,弹窗中有两个下拉框,起始时刻和终止时刻,范畴是 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();},
  },
};

次要逻辑是计算出起始时刻和终止时刻,脑子中有一些想法,然而代码总是编写有问题,因而记录下大佬的编码,再次感激边城大佬的帮忙。

退出移动版