el-date-picker 日期组件切换的坑

el-date-picker 日期组件切换的坑

问题描述:

问题1. 根据类型切换需要的时间选择器组件(搜索栏是一个form组件,里面有input、select、picker等,在使用的页面里传入指定的类型就能展示)第一次按顺序切换日常发,周常发,月常发是没问题的,但是当第二次选择周常发时,选择器无变化,然后再一次切换会出现上一次应该出现的选择器,并且会有 问题2. 选择器错位的现象

解决:

传给后端的值为 startTIme、endTime但实际选择器保存的是一个未格式化的时间,问题1:应该在每次切换select值后删除日期的值(为了处理后端需要的数据格式因此日 周 月保存的时间值是同一个)问题2:在form组件中给每个picker添加key

完整的formComponent组件

<!--
 * @Description: form组件 页面
 * @Use: type可选值:'',numberInput,select,dept,radio,switch,date,daterange,dateNoTime,datetimerange
 * @Author: mhf
 * @Date: 2023-06-29 17:08:33
-->
<!-- eslint-disable vue/no-mutating-props -->
<template>
  <div class="search-component">
    <!-- 表单区域 -->
    <el-form ref="formRef" :model="form" :inline="inline" :rules="formRules">
      <el-form-item
        v-for="(item, index) in formLabel"
        :key="index"
        :label="item.label + ' :'"
        :prop="item.value"
      >
        <el-input
          v-if="!item.type"
          v-model.trim="form[item.value]"
          :placeholder="'请输入' + item.label"
          size="small"
          :type="item.type ? item.type : 'text'"
        />
        <el-input
          v-if="item.type === 'numberInput'"
          v-model.number="form[item.value]"
          :placeholder="'请输入' + item.label"
          size="small"
        />
        <el-select
          v-if="item.type === 'select'"
          v-model.trim="form[item.value]"
          filterable
          :placeholder="'请选择' + item.label"
          clearable
          size="small"
        >
          <el-option
            v-for="(items, index) in item.opts"
            :key="index"
            :label="items[item.optLabel]"
            :value="items[item.optValue]"
            @click.native="selectClick(item, items)"
          />
        </el-select>
        <treeselect
          v-if="item.type === 'dept'"
          v-model="form[item.value]"
          class="treeBox"
          :options="item.opts"
          :show-count="true"
          :placeholder="'请选择' + item.label"
        />
        <template v-if="item.type === 'radio'">
          <el-radio
            v-for="items in item.opts"
            :key="items.value"
            v-model="form[item.value]"
            :label="items.value"
            >{
   
   { items.label }}
          </el-radio>
        </template>
        <el-switch v-if="item.type === 'switch'" v-model="form[item.value]" />
        <el-date-picker
          v-if="item.type === 'date'"
          key="date"
          v-model="form[item.value]"
          type="date"
          placeholder="选择日期"
          value-format="yyyy-MM-dd HH:mm:ss"
        />
        <el-date-picker
          v-if="item.type === 'dateNoTime'"
          key="dateNoTime"
          v-model="form[item.value]"
          type="date"
          placeholder="选择日期"
          value-format="yyyy-MM-dd"
        />
        <el-date-picker
          v-if="item.type === 'datetimerange'"
          key="datetimerange"
          v-model="form[item.value]"
          type="datetimerange"
          :picker-options="pickerOptions"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          align="right"
          value-format="yyyy-MM-dd HH:mm:ss"
        />
        <el-date-picker
          v-if="item.type === 'daterange'"
          key="daterange"
          v-model="form[item.value]"
          type="daterange"
          :picker-options="pickerOptions"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          align="right"
          value-format="yyyy-MM-dd"
          @change="daterangeChange"
        />
        <el-date-picker
          v-if="item.type === 'week'"
          key="week"
          v-model="form[item.value]"
          type="week"
          format="yyyy 第 WW 周"
          placeholder="选择周"
          @change="weekChange"
        >
        </el-date-picker>
        <el-date-picker
          v-if="item.type === 'month'"
          key="month"
          v-model="form[item.value]"
          type="month"
          placeholder="选择月"
          value-format="yyyy-MM-dd"
          @change="monthChange"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <slot name="formSlot" />
      </el-form-item>
      <div v-if="showOperationBtn" class="right-handle">
        <el-form-item>
          <el-button
            type="primary"
            size="small"
            icon="el-icon-search"
            @click="handleSearch"
            >查询
          </el-button>
          <el-button
            size="small"
            icon="el-icon-refresh"
            @click="handleResetFrom"
            >重置
          </el-button>
        </el-form-item>
        <el-form-item />
        <el-form-item>
          <slot name="handleSlot" />
        </el-form-item>
      </div>
    </el-form>
  </div>
</template>

<script>
export default {
  name: "SearchComponent",
  props: {
    inline: {
      type: Boolean,
      default: true,
    },
    // eslint-disable-next-line vue/require-default-prop
    form: {
      type: Object,
      required: true,
    },
    // eslint-disable-next-line vue/require-default-prop
    formLabel: {
      type: Array,
      required: true,
    },
    // eslint-disable-next-line vue/require-default-prop
    formRules: {
      type: Object,
      default: () => {
        return {};
      },
    },
    labelWidth: {
      type: Number,
      default: 90,
    },
    showOperationBtn: {
      type: Boolean,
      default: true,
    },
  },
  // 用来以对象方式存放数据
  data() {
    return {
      pickerOptions: {
        shortcuts: [
          {
            text: "今天",
            onClick(picker) {
              const startTime = new Date(new Date().setHours(0, 0, 0));
              const endTime = new Date(new Date().setHours(23, 59, 59));
              // const endTime = new Date(); //
              picker.$emit("pick", [startTime, endTime]);
            },
          },
          {
            text: "最近一周",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近一个月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近三个月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
              picker.$emit("pick", [start, end]);
            },
          },
        ],
      },
    };
  },

  created() {},
  mounted() {},
  methods: {
    selectClick(item, items) {
      this.$emit("selectChange", { item, items });
    },
    handleSearch() {
      this.$emit("handleSearch", this.form);
    },
    handleResetFrom() {
      this.$emit("handleResetFrom");
    },
    daterangeChange(val) {
      this.$emit("daterangeChange", val);
    },
    weekChange(val) {
      let timeArr = [];
      if (val) {
        let startTime = new Date(val.getTime()); //开始时间
        let endTime = new Date(val.getTime() + 24 * 60 * 60 * 1000 * 6); //结束时间
        timeArr = [
          startTime.toISOString().slice(0, 10),
          endTime.toISOString().slice(0, 10),
        ];
      }
      this.$emit("getTimeArr", timeArr);
    },
    monthChange(val) {
      const [year, month, day] = val.split("-");
      const endDate = new Date(year, month, 0).getDate();
      let timeArr = [`${year}-${month}-${day}`, `${year}-${month}-${endDate}`];
      this.$emit("getMonthArr", timeArr);
    },
  },
};
</script>

<style lang="scss" scoped>
.search-component {
  .right-handle {
    display: inline-block;
    margin-left: 30px;
  }
}
.treeBox {
  width: 242px;
}
</style>

使用的完整的页面

<!--
 * @Description: 常发拥堵路段 页面
 * @Author: mhf
 * @Date: 2023-09-14 15:46:36
-->
<template>
  <div>
    <newPageCompYt
      ref="newPageCompYt"
      idName="id"
      :formLabel="formLabel"
      :btnList="btnList"
      :tableData="tableData"
      :tableConfig="tableConfig"
      :tableDataColumn="tableDataColumn"
      :total="total"
      :paginationConfig.sync="paginationConfig"
      :pageSizes="pageSizes"
      :exportTypeAndUrl="exportTypeAndUrl"
      :customObj="customObj"
      @on-response="getBtnType"
      @resetForm="resetForm"
      @getTableData="getTableData"
      @daterangeChange="daterangeChange"
      @getTimeRange="getTimeRange"
      @getMonthArr="getMonthArr"
      @formSelectChange="formSelectChange"
    >
      <template slot="roadType" slot-scope="scope">
        <dict-tag
          :options="dict.type.traffic_road_type"
          :value="scope.row.roadType"
        />
      </template>

      <template slot="roadDirection" slot-scope="scope">
        <dict-tag
          :options="dict.type.traffic_road_direction"
          :value="scope.row.roadDirection"
        />
      </template>
    </newPageCompYt>
  </div>
</template>

<script>
import { getLastNumDay } from "@/utils/publicFun";
import { getRoadBlockList } from "@/api/statisticAnalysis/statisticAnalysis";

export default {
  name: "roadCongested",
  components: {},
  props: {},
  dicts: ["traffic_often_type", "traffic_road_type", "traffic_road_direction"],
  computed: {
    customObj() {
      let flag = false;
      if (this.paginationConfig.queryAllTime) {
        flag =
          this.paginationConfig.queryAllTime.length > 0 ||
          this.paginationConfig.queryAllTime !== [];
      } else {
        flag = false;
      }

      return {
        startTime: flag
          ? this.paginationConfig.queryAllTime[0] + " 00:00:00"
          : null,
        endTime: flag
          ? this.paginationConfig.queryAllTime[1] + " 23:59:59"
          : null,
        oftenType: this.paginationConfig.oftenType,
        pageNum: this.paginationConfig.pageNum,
        pageSize: this.paginationConfig.pageSize,
      };
    },
  },
  data() {
    return {
      formLabel: [
        {
          label: "常发类型",
          value: "oftenType",
          type: "select",
          opts: [],
          dict: "traffic_often_type",
          optLabel: "dictLabel",
          optValue: "dictValue",
        },
        {
          label: "日期",
          value: "queryAllTime",
          type: "daterange",
        },
      ],
      btnList: [
        {
          name: "导出",
          icon: "iconfont if-daochu",
          color: "#1492FF",
          hasPermi: "system:user:resetPwd",
        },
      ],
      tableData: [],
      tableConfig: {
        isLoading: false,
      },
      tableDataColumn: [
        { name: "序号", value: "index" },
        { name: "路段名称", value: "roadName" },
        { name: "道路方向", value: "roadDirection", isSlot: true },
        { name: "道路等级", value: "roadType", isSlot: true },
      ],
      total: 0,
      paginationConfig: {
        pageNum: 1,
        pageSize: 10,
      },
      pageSizes: [5, 10, 15, 20],
      exportTypeAndUrl: {
        isCustom: true,
        exportType: "trafficTrend",
        exportUrl: "/trafficRun/dataReport/congestedRoad",
      },
    };
  },
  methods: {
    getTableData() {
      this.tableConfig.isLoading = true;
      const { queryAllTime, ...obj } = this.paginationConfig;
      getRoadBlockList(obj).then((response) => {
        this.tableData = response.data.rows !== null ? response.data.rows : [];
        this.total = response.data.total;
        this.tableConfig.isLoading = false;
      });
    },

    getSETime(timeArr) {
      if (timeArr.length > 0) {
        this.$set(this.paginationConfig, "startTime", timeArr[0] + " 00:00:00");
        this.$set(this.paginationConfig, "endTime", timeArr[1] + " 23:59:59");
      } else {
        this.$set(this.paginationConfig, "startTime", null);
        this.$set(this.paginationConfig, "endTime", null);
      }
    },

    daterangeChange(timeRange) {
      this.getSETime(timeRange);
    },

    getTimeRange(timeRange) {
      this.getSETime(timeRange);
    },

    getMonthArr(timeRange) {
      this.getSETime(timeRange);
    },

    weekChange(val) {
      // let timeArr = []
      // if (val) {
      //   let startTime = new Date(val.getTime()); //开始时间
      //   let endTime = new Date(val.getTime() + (24 * 60 * 60 * 1000) * 6); //结束时间
      //   timeArr = [startTime.toISOString().slice(0, 10), endTime.toISOString().slice(0, 10)];
      // }
    },

    formSelectChange(obj) {
      if (obj.item.label === "常发类型") {
        let arr = [
          {
            label: "日期",
            value: "queryAllTime",
            type: "daterange",
          },
          {
            label: "日期",
            value: "queryAllTime",
            type: "week",
          },
          {
            label: "日期",
            value: "queryAllTime",
            type: "month",
          },
        ];
        this.formLabel[1] = arr[obj.items.dictValue - 1]
        this.$set(this.paginationConfig, 'queryAllTime', null)
        delete this.paginationConfig.queryAllTime  // 主要是这步 清空原先保存的值(问题1)
        this.getSETime([])
      }
    },

    getBtnType(type) {
      console.log(type);
    },

    resetForm() {
      let timeArr = getLastNumDay(30, false);
      this.$set(this.paginationConfig, "queryAllTime", timeArr);
      this.$set(this.paginationConfig, "startTime", timeArr[0]);
      this.$set(this.paginationConfig, "endTime", timeArr[1]);
      this.$set(this.paginationConfig, "oftenType", "1");
      this.formLabel[1] = {
        label: "日期",
        value: "queryAllTime",
        type: "daterange",
      };
    },
  },

  created() {
    this.resetForm();
  },

  mounted() {},
};
</script>

<style lang="scss" scoped></style>

问题2 看此段即可

<el-date-picker
          v-if="item.type === 'datetimerange'"
          key="datetimerange"
          v-model="form[item.value]"
          type="datetimerange"
          :picker-options="pickerOptions"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          align="right"
          value-format="yyyy-MM-dd HH:mm:ss"
        />

扫描二维码关注公众号,回复: 17331278 查看本文章

猜你喜欢

转载自blog.csdn.net/m0_74149462/article/details/135287499