
- <div>
- <el-date-picker
- v-model="dateModel"
- type="datetimerange"
- :picker-options="pickerOptions"
- range-separator="至"
- ref="picker"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- :default-time="defaultTime"
- />
- div>
-
- <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>
- <div id="app">
-
- <myDatePicker
- v-model="date"
- :limit="10"
- :daysLimit="30"
- disableCurrentDateLater
- />
- div>
-
- <script>
- import myDatePicker from './components/myDatePicker'
- export default {
- name: 'App',
- components: {
- myDatePicker,
- },
- data() {
- return {
- date: [],
- }
- },
- }
- script>
-