el-date-picker 封装一个简单的日期组件, 主要是禁用日期

子组件

<template>
    <div>
        <el-date-picker
        v-model="dateModel"
        type="datetimerange"
        :picker-options="pickerOptions"
        range-separator="至"
        ref="picker"
        start-placeholder="开始日期"
        end-placeholder="结束日期"
        :default-time="defaultTime"
      />
    </div>
</template>

<script>
// 定义一天的毫秒数
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
export default {
    props: {
        // 日期范围值
        value: {
            type: Array,
            default: () => []
        },
        // 选择的日期范围限制
        limit: {
            type: Number,
            default: Infinity
        },
        // 是否禁止选择当前日期之后的日期
        disableCurrentDateLater:{
            type:Boolean,
            default: false
        },
        // 只能选择当前日期之前的天数限制
        daysLimit: {
            type: Number,
            default: Infinity
        },
        // 是否显示快捷选项
        showShortcuts:{
            type:Boolean,
            default: true
        },
        // 默认开始和结束时间的时分秒
        defaultTime:{
            type: Array,
            default: () => (['00:00:00', '23:59:59'])
        }
    },
    data() {
        return {
            // 日期选择器的选项
            pickerOptions: {
                onPick: this.handlePick,
                disabledDate: this.isDisabledDate,
                shortcuts: this.showShortcuts ? this.getShortcuts() : [],
            },
        };
    },
    methods: {
        // 处理日期选择
        // 当选择的最小日期存在时,如果已经存在pickerMinDate,则将其置空;如果不存在pickerMinDate,则将选择的最小日期赋值给pickerMinDate
        handlePick({ minDate }) {
            const now = new Date();
            now.setSeconds(0, 0); // 清除秒和毫秒
            if (minDate && this.pickerMinDate) {
                this.pickerMinDate = null;
            } else if (minDate) {
                this.pickerMinDate = minDate.getTime();
            }
        },
        // 判断日期是否被禁用
        // 如果pickerMinDate存在,则判断日期是否超出范围或者在当前日期之后;如果pickerMinDate不存在,则判断日期是否在30天前或者在当前日期之后
        isDisabledDate(time) {
            const now = new Date();
            const thirtyDaysAgo = now.getTime() - this.daysLimit * ONE_DAY_MS;
            if (this.pickerMinDate) {
                return this.isDateOutOfRange(time, thirtyDaysAgo, this.pickerMinDate) || this.isDateAfterNow(time, now);
            }
            return time.getTime() < thirtyDaysAgo || this.isDateAfterNow(time, now);
        },

        // 判断日期是否超出范围
        // 如果日期在pickerMinDate的limit天之后,或者在pickerMinDate的limit天之前,或者在30天前,则返回true,表示日期超出范围
        isDateOutOfRange(time, thirtyDaysAgo, pickerMinDate) {
            const limitTime = this.limit * ONE_DAY_MS;
            return (time.getTime() > (pickerMinDate + limitTime)) || (time.getTime() < (pickerMinDate - limitTime)) || time.getTime() < thirtyDaysAgo;
        },

        // 判断日期是否在当前日期之后
        isDateAfterNow(time, now) {
            return this.disableCurrentDateLater && time.getTime() > now.getTime();
        },

        // 获取快捷选项
        getShortcuts() {
            return [{
                text: '最近一周',
                onClick: this.getShortcutPicker(7)
            }, {
                text: '最近一个月',
                onClick: this.getShortcutPicker(30)
            }, {
                text: '最近三个月',
                onClick: this.getShortcutPicker(90)
            }];
        },
        // 获取快捷选项的日期范围
        getShortcutPicker(days) {
            return (picker) => {
                const end = new Date();
                const start = new Date();
                start.setTime(start.getTime() - days * ONE_DAY_MS);
                picker.$emit('pick', [start, end]);

            };
        },
    },
    computed: {
        // 日期模型,用于v-model双向绑定
        dateModel: {
            get() {
                return this.value ? this.value.map(date => new Date(date)) : [];
            },
            set(val) {
                if (val) {
                    this.$emit('input', val.map(date => date.getTime()));
                } else {
                    this.$emit('input', null);
                }
            }
        }
    },
};
</script>

父组件

<template>
  <div id="app">
     <!--
          disableCurrentDateLater  当前时间之后的日期是否禁止选择
          limit 选择的范围: 比如: 只能选1月1日前后的30天 ,这里就传30
          daysLimit 只能选择当前时间之前的多少天
      -->
            <myDatePicker
                v-model="date"
                :limit="10"
                :daysLimit="30"
                disableCurrentDateLater
            />
  </div>
</template>

<script>
import myDatePicker from './components/myDatePicker'
export default {
  name: 'App',
  components: {
    myDatePicker,
  },
  data() {
    return {
      date: [],
    }
  },
}
</script>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值