|
2 | 2 | * Created by Liu.Jun on 2020/7/22 13:21.
|
3 | 3 | */
|
4 | 4 |
|
| 5 | +const f = s => `0${s}`.substr(-2); |
| 6 | + |
| 7 | +function formatDateStr(date, isDatetime) { |
| 8 | + if (!date) return ''; |
| 9 | + |
| 10 | + const dateObj = new Date(date); |
| 11 | + |
| 12 | + if (isDatetime) return dateObj.toISOString(); |
| 13 | + |
| 14 | + const { year, month, day } = { |
| 15 | + year: dateObj.getFullYear(), |
| 16 | + month: dateObj.getMonth() + 1, |
| 17 | + day: dateObj.getDate(), |
| 18 | + }; |
| 19 | + return `${year}-${f(month)}-${f(day)}`; |
| 20 | +} |
| 21 | + |
| 22 | +function isEmptyValue(value) { |
| 23 | + return value === null || value === '' || (Array.isArray(value) && value.every(item => item === '')); |
| 24 | +} |
| 25 | + |
5 | 26 | export default {
|
6 | 27 | name: 'DatePickerWidget',
|
7 |
| - functional: true, |
8 |
| - render(h, context) { |
9 |
| - const { isNumberValue, isRange, ...otherProps } = context.data.attrs || {}; |
10 |
| - |
11 |
| - context.data.attrs = { |
12 |
| - type: isRange ? 'daterange' : 'date', |
13 |
| - 'value-format': isNumberValue ? 'timestamp' : 'yyyy-MM-dd', |
14 |
| - ...otherProps |
| 28 | + props: { |
| 29 | + value: { |
| 30 | + type: null |
| 31 | + }, |
| 32 | + isNumberValue: { |
| 33 | + type: Boolean, |
| 34 | + default: false |
| 35 | + }, |
| 36 | + isDatetime: { |
| 37 | + type: Boolean, |
| 38 | + default: false |
| 39 | + }, |
| 40 | + isRange: { |
| 41 | + type: Boolean, |
| 42 | + default: false |
| 43 | + } |
| 44 | + }, |
| 45 | + data() { |
| 46 | + return { |
| 47 | + originValue: this.value, |
| 48 | + formatValue: this.formatDate(this.value) |
15 | 49 | };
|
| 50 | + }, |
| 51 | + watch: { |
| 52 | + value(newVal) { |
| 53 | + // 兼容 iview 绑定字符串类型值会导致无限循环的问题 |
16 | 54 |
|
17 |
| - const oldInputCall = context.data.on.input; |
18 |
| - context.data.on = { |
19 |
| - ...context.data.on, |
20 |
| - input(val) { |
21 |
| - const trueVal = val === null ? (isRange ? [] : undefined) : val; |
22 |
| - oldInputCall.apply(context.data.on, [trueVal]); |
| 55 | + if (newVal === this.formatValue) { |
| 56 | + // 内部date-picker选择框更新 |
| 57 | + } else { |
| 58 | + // 外部更新值 |
| 59 | + this.originValue = newVal; |
23 | 60 | }
|
24 |
| - }; |
| 61 | + } |
| 62 | + }, |
| 63 | + computed: { |
| 64 | + type() { |
| 65 | + return this.isDatetime |
| 66 | + ? (this.isRange ? 'datetimerange' : 'datetime') |
| 67 | + : (this.isRange ? 'daterange' : 'date'); |
| 68 | + } |
| 69 | + }, |
| 70 | + methods: { |
| 71 | + formatDate(val) { |
| 72 | + const { isRange, isNumberValue, isDatetime } = this.$props; |
25 | 73 |
|
26 |
| - return h('el-date-picker', context.data, context.children); |
| 74 | + let trueVal; |
| 75 | + if (isRange) { |
| 76 | + trueVal = isEmptyValue(val) |
| 77 | + ? [] |
| 78 | + : val.map( |
| 79 | + item => (isNumberValue ? (new Date(item)).valueOf() : formatDateStr(item, isDatetime)) |
| 80 | + ); |
| 81 | + } else { |
| 82 | + trueVal = isEmptyValue(val) |
| 83 | + ? undefined |
| 84 | + : isNumberValue ? (new Date(val)).valueOf() : formatDateStr(val, isDatetime); |
| 85 | + } |
| 86 | + return trueVal; |
| 87 | + } |
| 88 | + }, |
| 89 | + render(h) { |
| 90 | + const self = this; |
| 91 | + return h('date-picker', { |
| 92 | + attrs: { |
| 93 | + type: this.type, |
| 94 | + value: this.originValue, |
| 95 | + ...this.$attrs |
| 96 | + }, |
| 97 | + on: { |
| 98 | + ...this.$listeners, |
| 99 | + input(val) { |
| 100 | + self.originValue = val; |
| 101 | + self.formatValue = self.formatDate(val); |
| 102 | + |
| 103 | + self.$emit('input', self.formatValue); |
| 104 | + } |
| 105 | + } |
| 106 | + }); |
27 | 107 | }
|
28 | 108 | };
|
0 commit comments