vue2 组件封装 el-date-picker 日期

 

基本使用都满足

 

包括常用的:

     时间格式 :type [date,datetime,daterange ....]

     快捷方式 :日期左侧:如 今天,昨天,一个月前日期

    日期禁用:禁用日期段

    其它相关属性

 

custom-date-picker 组件内容
<!--
   1、isShortcut <boolean> 是否显示快捷方式.默认 true显示 ,false 不显示
-->

<template>
  <div class="custom-date-picker">
    <el-date-picker
      v-model="dateValue"
      :type="type"
      :format="format"
      :value-format="valueFormat"
      :placeholder="placeholder"
      :disabled="disabled"
      :clearable="clearable"
      :readonly="readonly"
      :picker-options="pickerOptions"
      :range-separator="rangeSeparator"
      :start-placeholder="startPlaceholder"
      :end-placeholder="endPlaceholder"
      @change="handleChange"
      @blur="handleBlur"
      @focus="handleFocus"
    ></el-date-picker>
  </div>
</template>

<script>
export default {
  name: "CustomDatePicker",
  props: {
    // 绑定值(v-model)
    value: {
      type: [String, Number, Date, Array], // 单日期为String/Date,范围选择为Array
      default: null,
    },
    // 日期类型:date/datetime/date-range/datetime-range等
    type: {
      type: String,
      default: "date",
    },
    // style: {
    //   type: Object,
    //   default: () => {},
    // },
    // 显示格式(如 'yyyy-MM-dd')
    format: {
      type: String,
      default() {
        // 根据类型默认格式
        return this.type.includes("datetime")
          ? "yyyy-MM-dd HH:mm:ss"
          : "yyyy-MM-dd";
      },
    },
    // 绑定值格式(传给后端的格式)
    valueFormat: {
      type: String,
      default() {
        return this.type.includes("datetime")
          ? "yyyy-MM-dd HH:mm:ss"
          : "yyyy-MM-dd";
      },
    },
    // 占位符
    placeholder: {
      type: String,
      default: "请选择日期",
    },
    // 范围选择时的开始占位符
    startPlaceholder: {
      type: String,
      default: "开始日期",
    },
    // 范围选择时的结束占位符
    endPlaceholder: {
      type: String,
      default: "结束日期",
    },
    // 范围选择分隔符
    rangeSeparator: {
      type: String,
      default: "",
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // 是否可清空
    clearable: {
      type: Boolean,
      default: true,
    },
    // 是否只读
    readonly: {
      type: Boolean,
      default: false,
    },
    // 禁用日期的回调函数(如禁用过去日期:(time) => time < Date.now() - 8.64e7)
    disabledDate: {
      type: Function,
      default: () => false, // 默认返回 false(所有日期都可选择)
    },
    // 默认显示。快捷类型 1、显示;0不显示
    isShortcut: {
      type: [String, Number, Boolean],
      default: true,
    },
    // 错误提示信息(配合表单校验)
    errorMsg: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      dateValue: this.value, // 内部绑定值
      pickerOptions: null,
      pickerOptionsDate: {
        shortcuts: [
          {
            text: "今天",
            onClick(picker) {
              picker.$emit("pick", new Date());
            },
          },
          {
            text: "一周前",
            onClick(picker) {
              const date = new Date();
              date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit("pick", date);
            },
          },
          {
            text: "一个月前",
            onClick(picker) {
              const date = new Date();
              date.setTime(date.getTime() - 3600 * 1000 * 24 * 30);
              picker.$emit("pick", date);
            },
          },
        ],
        disabledDate: this.disabledDate,
        // disabledDate(time) {
        //   return time.getTime() > Date.now() - 8.64e6 // 只能选择今天及今天之前的日期
        // }
      },
      pickerOptionsRange: {
        shortcuts: [
          {
            text: "今天",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime());
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近三天",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 3);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            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]);
            },
          },
          {
            text: "最近半年",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 180);
              picker.$emit("pick", [start, end]);
            },
          },
        ],
        disabledDate: this.disabledDate,

        // disabledDate(time) {
        //   return time.getTime() > Date.now() - 8.64e6 // 只能选择今天及今天之前的日期
        // }
      },
    };
  },
  mounted() {
    this.initType(this.type);
  },
  // computed
  watch: {
    // 监听外部value变化,同步到内部
    value: {
      handler(val) {
        this.dateValue = val;
      },
      immediate: true,
      deep: true, // 范围选择时需要深度监听
    },
    // 内部值变化,同步到外部(v-model)
    dateValue(val) {
      this.$emit("input", val);
    },
  },
  methods: {
    initType(type) {
      // 快捷方式 true显示; false 不显示
      if (this.isShortcut) {
        if (type === "daterange") {
          this.pickerOptions = this.pickerOptionsRange;
        } else {
          this.pickerOptions = this.pickerOptionsDate;
        }
      } else {
        // 是否有禁用时间段
        if (this.disabledDate) {
          this.pickerOptions = {
            disabledDate: this.disabledDate,
          };
        } else {
          this.pickerOptions = null;
        }
      }
    },
    // 日期变化时触发
    handleChange(val) {
      this.$emit("change", val);
    },
    // 失焦事件
    handleBlur(e) {
      this.$emit("blur", e);
    },
    // 聚焦事件
    handleFocus(e) {
      this.$emit("focus", e);
    },
    // 手动清空(可外部调用)
    clear() {
      this.dateValue = null;
    },
  },
};
</script>

<style lang="scss" scoped>
.custom-date-picker {
  .el-date-editor--date {
    width: 100% !important;
  }

  .el-date-editor--daterange {
    width: 100% !important;
    padding-left: 6px;
    padding-right: 0;

    ::v-deep .el-range-separator {
      padding: 0 3px;
    }

    ::v-deep .el-range__close-icon {
      width: 20px;
    }
  }
}
</style>

 

 
import DatePickerTime from "./DatePicker/CustomDatePicker.vue";

 

页面调用。   date-picker-time

   <el-form-item label="时间1" prop="time1">
        <date-picker-time
          type="date"
          v-model="ruleForm.time1"
        ></date-picker-time>
      </el-form-item>

 

image

 

 

 如果默认不展示快捷方式  

:is-shortcut="false"
<el-form-item label="时间1" prop="time1">
        <date-picker-time
          type="date"
          :is-shortcut="false"
          v-model="ruleForm.time1"
        ></date-picker-time>
      </el-form-item>

 

image

 

 

禁用日期段

   <date-picker-time
          type="daterange"
          :is-shortcut="false"
          v-model="ruleForm.time1"
          :disabledDate="handleDisabledDate"
        ></date-picker-time>
      </el-form-item>

 

  methods: {
    handleDisabledDate(time) {
      // 禁用过去的日期
       return time.getTime() < new Date().setHours(0, 0, 0, 0);
      // 禁用未来时间
    //   return time.getTime() > new Date().setHours(0, 0, 0, 0);
    },

 

image

 

 

value-format="yyyy-MM-dd hh:mm:ss"
 
<!-- 日期时间 含有 时分秒 14位数字-->
value-format="yyyyMMddHHmmss"

posted on 2025-10-29 17:08  Mc525  阅读(5)  评论(0)    收藏  举报

导航