element-ui 通过按钮式触发日期选择器

element ui

  • 写在前面
  • [1. 自定义的日期时间组件CustomDatePicker.vue](#1. 自定义的日期时间组件CustomDatePicker.vue)
  • [2. 页面效果](#2. 页面效果)
  • 总结
  • 写在最后

写在前面

需求:elementui中日期时间选择器,目前只能通过点击input输入框触发日期选择器,我希望能通过其他方式触发日期选择器同时把input输入框去掉,如点击按钮

1. 自定义的日期时间组件CustomDatePicker.vue

java 复制代码
<template>
  <div class="date-input">
    <el-input
      v-model="startDateStr"
      :placeholder="$t('task.taskStartTime')"
      type="text"
      clearable
      class="date-input-field"
      @input="validateDate"
    />
    <span class="line"></span>
    <el-input
      v-model="endDateStr"
      :placeholder="$t('task.taskFinishTime')"
      type="text"
      clearable
      class="date-input-field"
      @blur="validateDate"
    />
    <div class="icon-container" @click="toggleDatePicker">
      <i class="el-icon-date" style="font-size: 24px;"></i>
    </div>
    <el-date-picker
      style="
        position: absolute;
        z-index: -100;
        top: 15px;
        left: -178px;
        transform: scale(0.1);
      "
      size="mini"
      v-model="selectedDateRange"
      :editable="false"
      type="datetimerange"
      @change="onDateChange"
      ref="timePick"
      value-format="yyyy-MM-dd HH:mm:ss"
    />
  </div>
</template>

<script>

export default {
  props: {
    // 父组件传过来的值  
    customTimePicker: {  
      type: Array,  
      default: () => {
              return [new Date(), new Date()]
            }  
    },  
  },
  data() {
    return {
      selectedDateRange: [],
      startDateStr: "",
      endDateStr: "",
      error: ''
    };
  },
  created(){
    console.log('====> customTimePicker', this.customTimePicker);
  },
  watch: {
    customTimePicker: {
      handler(newVal) {
        console.log('customTimePicker==>newVal', newVal);
        if (newVal && newVal.length === 2) {
          this.selectedDateRange = [...newVal];
          this.startDateStr = newVal[0];
          this.endDateStr = newVal[1];
        }
      },
      deep: true
    },
    selectedDateRange: {
      handler(newVal, oldVal) {
        if (newVal && newVal.length === 2) {
          if(oldVal && newVal.toString() === oldVal.toString()) {
            return;
          } else {
            this.startDateStr = newVal[0].toString().replace('T', ' ');
            this.endDateStr = newVal[1].toString().replace('T', ' ');
            this.$emit('input', newVal);
          }
        }
      },
      deep: true
    },
    startDateStr(newVal, oldVal) {
      if(oldVal && newVal.toString() === oldVal.toString()) {
        return;
      } else {
        this.selectedDateRange[0] = newVal.toString().replace('T', ' ');
        this.$emit('input', this.selectedDateRange);
      }
    },
    endDateStr(newVal, oldVal) {
      if(oldVal && newVal.toString() === oldVal.toString()) {
        return;
      } else {
        this.selectedDateRange[1] = newVal.toString().replace('T', ' ');
        this.$emit('input', this.selectedDateRange);
      }
    }
  },
  methods: {
    validateDate() {
      const value = this.startDateStr;
      if (value.trim() === '') {
        this.error = '';
        this.$emit('updateError', this.error);
        return;
      }

      // 验证格式
      const regex = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/;
      const match = value.match(regex);

      if (!match) {
        this.$message.error('Invalid date format. Please use yyyy-MM-dd HH:mm:ss.');
        //this.error = 'Correct format is yyyy-MM-dd HH:mm:ss';
        // this.$emit('updateError', this.error);
        return;
      }

      // 解析日期
      const [year, month, day, hours, minutes, seconds] = match.slice(1).map(Number);

      // 检查年份是否在合理范围内
      if (year < 1900 || year > 2100) {
        this.$message.error('Invalid year. Please enter a year between 1900 and 2100.');
        // this.error = 'please input valid year';
        // this.$emit('updateError', this.error);
        return;
      }

      // 检查月份是否在1到12之间
      if (month < 1 || month > 12) {
        this.$message.error('Invalid month. Please enter a month between 1 and 12.');
        // this.error = 'please input valid month';
        // this.$emit('updateError', this.error);
        return;
      }

      // 检查日期是否在1到当月的最大天数之间
      const daysInMonth = new Date(year, month, 0).getDate();
      if (day < 1 || day > daysInMonth) {
        this.$message.error('Invalid day. Please enter a day between 1 and the maximum number of days in the selected month.');
        // this.error = 'please input valid day';
        // this.$emit('updateError', this.error);
        return;
      }

       // 检查小时是否在0到23之间
       if (hours < 0 || hours > 23) {
        this.$message.error('Invalid hour. Please enter an hour between 0 and 23.');
        // this.error = 'please input valid hour';
        // this.$emit('updateError', this.error);
        return;
      }

      // 检查分钟是否在0到59之间
      if (minutes < 0 || minutes > 59) {
        this.$message.error('Invalid minute. Please enter a minute between 0 and 59.');
        // this.error = 'please input valid minute';
        // this.$emit('updateError', this.error);
        return;
      }

      // 检查秒是否在0到59之间
      if (seconds < 0 || seconds > 59) {
        this.$message.error('Invalid second. Please enter a second between 0 and 59.');
        // this.error = 'please input valid second';
        // this.$emit('updateError', this.error);
        return;
      }

      // 创建日期对象
      const date = new Date(year, month - 1, day, hours, minutes, seconds);

      // 检查日期是否有效
      if (isNaN(date.getTime())) {
        this.$message.error('Invalid date. Please enter a valid date.');
        // this.error = 'please input valid date';
        // this.$emit('updateError', this.error);
        return;
      }

      this.error = '';
      this.$emit('updateError', this.error);
    },
    toggleDatePicker() {
      //触发日期框展开
      //  document
      //     	.querySelector(".time-date-picker")
      //     	.querySelector("input")
      //     	.focus();
      this.$refs.timePick.focus();
    },
    onDateChange(date) {
      this.startDateStr = date[0];
      this.endDateStr = date[1];
      this.$set(this, 'selectedDateRange', [this.startDateStr, this.endDateStr])
      this.$emit('input', this.selectedDateRange);
    },
    
  },
};
</script>

<style scoped>
.date-input {
  display: flex;
  align-items: center;
  position: relative; /* 为绝对定位的日期选择器提供相对定位 */
}

.date-input-field {
  width: 18%;
  /* flex-grow: 1; /* 让输入框占满剩余空间 */
  /* margin: 0; /* 删除外边距 */
  z-index: 10;
}

.icon-container {
  display: flex;
  align-items: center;
  justify-content: center;
  /*width: 30px; /* 正方形框的宽度 */
  /*height: 30px; /* 正方形框的高度 */
  /*border: 1px solid #ccc; /* 正方形框的边框 */
  cursor: pointer;
  /*background-color: #f9f9f9; /* 可以选择性添加背景色 */

  background: transparent;
  color: #008ed0;
  /*border: 1px solid #008ed0;
}

.icon {
  font-size: 16px; /* 调整图标大小 */
  font-weight: bold; /* 粗体字 */
  margin: 0; /* 删除图标的外边距 */
}
/*
.timePickCSS {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;
}
*/
.line {
  display: inline-block;
  width: 10px;
  height: 2px;
  background-color: #005987;
}
</style>

2. 页面效果

总结

写这篇博客主要的目的是让自己更深刻,有回忆点,然后就是分享自己的做法;有需要的根据自己的需求进行修改

写在最后

如果此文对您有所帮助,请帅戈靓女们 务必不要吝啬你们的Zan ,感谢!!不懂的可以在评论区评论,有空会及时回复。

相关推荐
滿14 小时前
Vue3 + Element Plus 动态表单实现
javascript·vue.js·elementui
ドロロ80615 小时前
element-plus点击重置表单,却没有进行重置操作
javascript·vue.js·elementui
緑水長流*z2 天前
(14)Element Plus项目综合案例
vue.js·elementui·vue3·element plus·elementplus项目·完整项目案例·项目学习笔记
牧杉-惊蛰3 天前
VUE+ElementUI 使用el-input类型type=“number” 时,取消右边的上下箭头
前端·vue.js·elementui
小小弯_Shelby3 天前
ElementUI 表格el-table自适应高度设置
前端·elementui
愛芳芳5 天前
springboot+mysql+element-plus+vue完整实现汽车租赁系统
前端·vue.js·spring boot·后端·mysql·elementui·汽车
漫无目的行走的月亮6 天前
VUE实现todolist
前端·vue.js·elementui
淘源码d10 天前
一套SaaS ERP管理系统源码,支持项目二开商用,SpringBoot+Vue+ElementUI+UniAPP
vue.js·spring boot·elementui·erp·erp系统·erp源码
好名字082110 天前
el-tabs与table样式冲突导致高度失效问题解决(vue2+elementui)
前端·vue.js·elementui
qq_2780637110 天前
vue elementui 去掉默认填充 密码input导致的默认填充
前端·vue.js·elementui