一、背景

基于element的日期时间组件,自行封装组件:

达到效果:(选择dateType日期类型,包括年月日,然后给后端传不同的开始日期和结束日期)

当选择年的时候,时间间隔为年,可以选择开始年和结束年;

当选择月的时候,时间间隔为月,可以选择开始年份月和结束年月;

当选择日的时候,时间间隔为日,可以选择开始年月日和结束年月日;

二、实现效果

 

三、代码

封装组件,实现代码如下:

<script setup>
import { nextTick, onMounted, reactive } from "vue";
import { getAssetsFile, throttle } from "@/utils";
import { frontOneHour, getTimeList } from "@/utils/replaceTime";
// 节流函数
export const throttle = (func, delay) => {
    let timeoutId;
    let lastExecTime = 0;

    return function (...args) {
        const currentTime = Date.now();

        if (currentTime - lastExecTime < delay) {
            // 上次执行时间距当前时间未超过指定延迟,不执行函数
            clearTimeout(timeoutId);
            timeoutId = setTimeout(() => {
                lastExecTime = currentTime;
                func.apply(this, args);
            }, delay);
        } else {
            // 上次执行时间距当前时间已超过指定延迟,立即执行函数
            lastExecTime = currentTime;
            func.apply(this, args);
        }
    };
}
//用法:frontOneHour('yyyy-MM-dd hh:mm:ss') // "2018-06-20 16:11:59"
function frontOneHour(_dateTime, fmt) {
  let currentTime
  if (!_dateTime) {
    currentTime = new Date(new Date().getTime())
  } else {
    currentTime = _dateTime
  }
  // console.log(132,currentTime) // Wed Jun 20 2018 16:12:12 GMT+0800 (中国标准时间)
  let o = {
    'M+': currentTime.getMonth() + 1, // 月份
    'd+': currentTime.getDate(), // 日
    'h+': currentTime.getHours(), // 小时
    'm+': currentTime.getMinutes(), // 分
    's+': currentTime.getSeconds(), // 秒
    'q+': Math.floor((currentTime.getMonth() + 3) / 3), // 季度
    'S': currentTime.getMilliseconds() // 毫秒
  }
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (currentTime.getFullYear() + '').substr(4 - RegExp.$1.length))
  for (var k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
  }
  return fmt
}
const data = reactive({
  isTips: "",
  isFinish: 1,
  btnDelay: 3000,
  currentSwitch: "other",
  valueTwoTimer: [],
});
const myType = [
  {
    label: "年",
    value: "year",
  },
  {
    label: "月",
    value: "month",
  },
  {
    label: "其它",
    value: "other",
  },
];

let delayTimer = null;
onMounted(() => {
  getTimerPiker(); //默认选中,最近12小时
  nextTick(() => {
    handleClickLook();
  });
});
const setTimeRange = (time) => {
  return time.getTime() >= Date.now() - 8.64e6;
};
const handleClickBtn = (val) => {
  const isThis = myType[val];
  data.currentSwitch = myType[val];
  console.log("ajing>>>", val, 22, isThis);
};
const handleClickLook = throttle(async () => {
  data.isFinish = 1;
  data.isTips = "加载中...";
  let info = {
    startTime: data.valueTwoTimer[0],
    endTime: data.valueTwoTimer[1],
  };
  //   const resApiData = await getInteilEnergyTotal(info); //接口数据
  const resApiData = false;
  console.log("resApiData>>>", resApiData);
  if (resApiData === false) {
    delayTimer = setTimeout(() => {
      data.isFinish = 2;
      data.isTips = "暂未接入";
    }, data.btnDelay);
    return;
  } else {
    if (resApiData.length && resApiData.length !== 0) {
      data.isFinish = 4;
      data.isTips = "接口数据获取成功";
    } else {
      data.isFinish = 3;
      data.isTips = "暂无数据";
      ElMessage({
        type: "warning",
        message: "暂无数据!",
      });
    }
  }
}, data.btnDelay);
const getTimerPiker = () => {
  let newData = new Date();
  let nowMonth = frontOneHour(newData, "yyyy-MM-dd hh:mm:ss");
  const front12Hour = new Date(newData.getTime() - 12 * 60 * 60 * 1000);
  let beforeMonth = frontOneHour(front12Hour, "yyyy-MM-dd hh:mm:ss");
  data.valueTwoTimer.push(beforeMonth);
  data.valueTwoTimer.push(nowMonth);
};
</script>

<template>
  <div class="myTimeRager_home">
    <div class="switchBox">
      <div class="leftBox">
        <div
          class="yearBtn"
          :class="data.currentSwitch == 'year' ? 'isActive' : 'yearBtn'"
          @click="handleClickBtn(0)"
        >
          年
        </div>
        <div
          class="yearBtn"
          :class="data.currentSwitch == 'month' ? 'isActive' : 'yearBtn'"
          @click="handleClickBtn(1)"
        >
          月
        </div>
        <div
          class="yearBtn2"
          :class="data.currentSwitch == 'other' ? 'isActive' : 'yearBtn2'"
          @click="handleClickBtn(2)"
        >
          自定义
        </div>
      </div>
      <div class="search_right">
        <template v-if="data.currentSwitch == 'year'">
          <el-date-picker
            v-model="data.valueTwoTimer[0]"
            type="year"
            format="YYYY"
            value-format="YYYY-MM-DD HH:mm:ss"
            placeholder="开始时间"
            style="width: 100px"
          >
          </el-date-picker>
          <div style="margin: 0px 15px 0px 30px">-</div>
          <el-date-picker
            v-model="data.valueTwoTimer[1]"
            format="YYYY"
            type="year"
            value-format="YYYY-MM-DD HH:mm:ss"
            placeholder="结束时间"
            style="width: 100px; margin-right: 20px"
          >
          </el-date-picker>
        </template>
        <template v-if="data.currentSwitch == 'month'">
          <el-date-picker
            v-model="data.valueTwoTimer"
            type="monthrange"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
        </template>
        <template
          v-if="data.currentSwitch !== 'year' && data.currentSwitch !== 'month'"
        >
          <el-date-picker
            :disabledDate="setTimeRange"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            v-model="data.valueTwoTimer"
            type="daterange"
            range-separator="-"
            value-format="YYYY-MM-DD HH:mm:ss"
            unlink-panels
          />
        </template>
      </div>
      <div class="rightBox">
        <el-button
          class="hdtbutton look"
          @click="handleClickLook"
          :loading="data.isFinish == 0"
        >
          查询
        </el-button>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.myTimeRager_home {
  width: 100%;
  height: 100%;
  .switchBox {
    width: 60%;
    height: 4.8%;
    margin-bottom: 10px;
    font-size: calc(100vw * 16 / 1920);
    display: flex;
    align-items: center;

    .isActive {
      font-weight: bold;
      color: #fff !important;
      background: #4279ca !important;
    }

    .switchBox1 {
      width: 110px;
      height: 90%;
      font-size: calc(100vw * 18 / 1920);
      color: rgba(93, 100, 110, 1);
      background: #f9fafc;
      // outline: 2px solid #fff;
      border-left: 4px solid rgba(93, 100, 110, 0.29);
      border-right: 4px solid rgba(93, 100, 110, 0.29);
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-right: 20px;
    }
    .leftBox {
      width: 24%;
      height: 100%;
      display: flex;
      .yearBtn {
        width: 36px;
        height: 100%;
        padding: 0px 10px;
        margin-right: 7px;
        color: #4279ca;
        background-color: #ebf0f5;
        border: 1px solid #fff;
        border-radius: 4px;
        display: flex;
        justify-content: center;
        align-items: center;
        &:hover {
          cursor: pointer;
        }
      }
      .yearBtn2 {
        .yearBtn;
        width: 70px;
      }
    }
    .search_right {
      width: 53%;
      height: 100%;
      display: flex;
      align-items: center;
      border-radius: 6px;
      border: 1px solid rgba(234, 243, 253, 1);
      background-color: rgba(247, 248, 250, 1);
      flex: 1;
      :deep(.el-date-editor) {
        --el-date-editor-datetimerange-width: 290px;
        .el-input__inner {
          text-align: center;
        }
      }
      :deep(.el-date-editor) {
        --el-date-editor-datetimerange-width: 290px;
        width: 400px !important;
        // height: 40px;
        --el-input-bg-color: rgba(247, 248, 250, 1);
        --el-input-border-color: rgba(247, 248, 250, 1);
        --el-input-focus-border-color: rgba(247, 248, 250, 1);
        --el-input-hover-border-color: rgba(247, 248, 250, 1);
      }
      .titleBox {
        width: 120px;
        height: 100%;
        text-align: center;
        background-color: #dae5f2;
        color: #5586cf;
        font-size: calc(100vw * 18 / 1920);
        display: flex;
        justify-content: center;
        align-items: center;
        overflow: hidden;
      }
    }
    .rightBox {
      .hdtbutton {
        width: 104px;
        height: 39px;
        border-radius: 6px 6px 6px 6px;
        padding: 0;
        display: inline-block;
        line-height: 39px;
        text-align: center;
        margin-left: 10px;
        font-size: calc(100vw * 20 / 1920);
        color: #ffffff;
      }
      .look {
        background-color: #4279ca;
      }
      .import {
        background-color: #3686bf;
      }
    }
  }
}
</style>

四、其它

组件封装,涉及其它的js方法的一些说明。。。

其它,备注:

1.查看按钮做了一个throttle节流,btnDelay按钮延迟时间默认设置为3s;

2.时间选择组件,默认填充时间,默认填充最近12小时,或者默认30天。 

1.按钮的节流

const handleClickLook = throttle(async () => {
   //function内部,可以写具体操作;也可以发起网络请求
   //const resApiData = await getInteilEnergyTotal(info); //接口数据
},btnDelay)

 2.时间组件默认填充时间

//js
//默认填充最近12小时 ==>  12 * 60 * 60 * 1000
const getTimerPiker = () => {
  let newData = new Date();
  let nowMonth = frontOneHour(newData, "yyyy-MM-dd hh:mm:ss");
  const front12Hour = new Date(newData.getTime() - 12 * 60 * 60 * 1000);
  let beforeMonth = frontOneHour(front12Hour, "yyyy-MM-dd hh:mm:ss");
  data.valueTwoTimer.push(beforeMonth);
  data.valueTwoTimer.push(nowMonth);
};

3.其它

/**
 * 获取一个延迟一小时的日期时间字符串
 * @param {string} _dateTime - 日期时间字符串,格式为'yyyy-MM-dd hh:mm:ss'。如果未提供,则使用当前日期时间。
 * @param {string} fmt - 输出日期时间字符串的格式。默认为'yyyy-MM-dd hh:mm:ss'。
 * @returns {string} - 在指定格式下延迟一小时的日期时间字符串。
 */
function frontOneHour(_dateTime, fmt = 'yyyy-MM-dd hh:mm:ss') {
  // 如果未提供_dateTime,则使用当前日期时间
  let currentTime = _dateTime ? _dateTime : new Date(new Date().getTime());

  // 对象,存储日期时间的不同部分
  let o = {
    'M+': currentTime.getMonth() + 1, // 月份
    'd+': currentTime.getDate(), // 日
    'h+': currentTime.getHours(), // 小时
    'm+': currentTime.getMinutes(), // 分钟
    's+': currentTime.getSeconds(), // 秒
    'q+': Math.floor((currentTime.getMonth() + 3) / 3), // 季度
    'S': currentTime.getMilliseconds() // 毫秒
  };
  
  // 将fmt中的格式字符串替换为日期时间的对应部分
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (currentTime.getFullYear() + '').substr(4 - RegExp.$1.length));
  }
  for (var k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
    }
  }
  return fmt;
}

 

 

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐