Skip to content

Commit dd6f2ea

Browse files
committed
feat: add valueType to format binding value
1 parent 3775970 commit dd6f2ea

File tree

8 files changed

+233
-71
lines changed

8 files changed

+233
-71
lines changed

README.md

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -69,34 +69,51 @@ export default {
6969
```
7070
### Props
7171

72-
| Prop | Type | Default | Description |
73-
|---------------------|---------------|-------------|-----------------------------------------------------|
74-
| type | String | 'date' | select date type (date/datetime/year/month/time) |
75-
| range | Boolean | false | if true, the type is daterange or datetimerange |
76-
| format | String | YYYY-MM-DD | The parsing tokens are similar to the moment.js |
77-
| lang | String/Object | zh | Translation ([custom](#lang))(en/zh/es/pt-br/fr/ru/de/it/cs) |
78-
| clearable | Boolean | true | if false, don't show the clear icon |
79-
| confirm | Boolean | false | if true, need click the button to change the value |
80-
| editable | Boolean | true | if false, user cann't type it |
81-
| disabled | Boolean | false | Disable the component |
82-
| placeholder | String | | input placeholder text |
83-
| width | String/Number | 210 | input size |
84-
| append-to-body | Boolean | false | append the popup to body |
85-
| popupStyle | Object | | popup style(override the top, left style) |
86-
| not-before | String/Date | '' | Disable all dates before new Date(not-before) |
87-
| not-after | String/Date | '' | Disable all dates after new Date(not-after) |
88-
| disabled-days | Array/function| [] | Disable Days |
89-
| shortcuts | Boolean/Array | true | the shortcuts for the range picker |
90-
| time-picker-options | Object | {} | set timePickerOptions(start, step, end) |
91-
| minute-step | Number | 0 | if > 0 don't show the second picker(0 - 60) |
92-
| first-day-of-week | Number | 7 | set the first day of week (1-7) |
93-
| input-class | String | 'mx-input' | the input class name |
94-
| input-name | String | 'date' | the input name attr |
95-
| input-attr | Object | | the input attr(eg: { required: true, id: 'input'}) |
96-
| confirm-text | String | 'OK' | the default text to display on confirm button |
97-
| range-separator | String | '~' | the range separator text |
98-
| date-format | String | '' | format the time header and tooltip |
72+
| Prop | Type | Accepted Values | Default | Description |
73+
|---------------------|---------------|-----------------|-------------|-----------------------------------------------------|
74+
| type | String | date/datetime/year/month/time | 'date' | select date type |
75+
| range | Boolean || false | if true, the type is daterange or datetimerange |
76+
| format | String || YYYY-MM-DD | The parsing tokens are similar to the moment.js |
77+
| value-type | String/Object | date/format/timestamp | 'date' | type of binding value. If not specified, the binding value will be a Date object(see [detail](#value-type)) |
78+
| lang | String/Object | en/zh/es/pt-br/fr/ru/de/it/cs | zh | Translation (set [how to custom](#lang)) |
79+
| clearable | Boolean || true | if false, don't show the clear icon |
80+
| confirm | Boolean || false | if true, need click the button to change the value |
81+
| editable | Boolean || true | if false, user cann't type it |
82+
| disabled | Boolean || false | Disable the component |
83+
| placeholder | String || | input placeholder text |
84+
| width | String/Number || 210 | input size |
85+
| append-to-body | Boolean || false | append the popup to body |
86+
| popupStyle | Object || | popup style(override the top, left style) |
87+
| not-before | String/Date || '' | Disable all dates before new Date(not-before) |
88+
| not-after | String/Date || '' | Disable all dates after new Date(not-after) |
89+
| disabled-days | Array/function|| [] | Disable Days |
90+
| shortcuts | Boolean/Array || true | the shortcuts for the range picker |
91+
| time-picker-options | Object || {} | set timePickerOptions(start, step, end) |
92+
| minute-step | Number | 0 - 60 | 0 | if > 0 don't show the second picker |
93+
| first-day-of-week | Number | 1 - 7 | 7 | set the first day of week |
94+
| input-class | String || 'mx-input' | the input class name |
95+
| input-attr | Object || | the input attr(eg: { required: true, id: 'input'}) |
96+
| confirm-text | String || 'OK' | the default text to display on confirm button |
97+
| range-separator | String || '~' | the range separator text |
98+
| date-format | String || '' | format the time header and tooltip |
99+
100+
#### value-type
101+
set the format of binding value
102+
103+
| Value | Description |
104+
|-----------------|-------------------------------------------|
105+
| date | binding value will be a Date object |
106+
| timestamp | binding value will be a timestamp number |
107+
| format | binding value will be the format string |
108+
109+
Advanced: You can also customize objects to implement two functions.
110+
```js
111+
{
112+
value2date: (value: any) => Date, // transform the binding value to calendar Date Object
113+
date2value: (date: Date) => any // transform the calendar Date Object to binding value
114+
}
99115

116+
```
100117

101118
#### lang
102119
* String (en/zh/es/pt-br/fr/ru/de/it/cs)

README.zh-CN.md

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -69,32 +69,52 @@ export default {
6969
```
7070
### Props
7171

72-
| Prop | Type | Default | Description
73-
|---------------------|---------------|-------------|-----------------------------------------------------
74-
| type | String | 'date' | 选择日期或日期时间(可选:date,datetime,year,month,time)
75-
| range | Boolean | false | 如果是true, 显示日历范围选择
76-
| format | String | YYYY-MM-DD | 格式化显示日期 api类似moment.js
77-
| lang | String/Object | zh | 选择语言或自定义 (en/zh/es/pt-br/fr/ru/de/it/cs)(custom)
78-
| clearable | Boolean | true | 如果设置false, 不显示清除图标
79-
| confirm | Boolean | false | 如果是true, 显示确认按钮且需要确认才更新时间
80-
| editable | Boolean | true | 如果是false, 用户不能手动输入更新日期
81-
| disabled | Boolean | false | 禁用组件
82-
| placeholder | String | | 输入框placeholder
83-
| width | String/Number | 210 | 设置宽度
84-
| append-to-body | Boolean | false | 弹出层放到body下面
85-
| popup-style | Object | | 弹出层的样式(可以覆盖left,top样式)
86-
| not-before | String/Date | '' | 禁止选择这个时间之前的时间
87-
| not-after | String/Date | '' | 禁止选择这个时间之前=后的时间
88-
| disabled-days | Array/function| [] | 自定义禁止的日期
89-
| shortcuts | Boolean/Array | true | 自定义范围选择的时候快捷选项(见下表)
90-
| time-picker-options | Object | {} | 自定义时间选择的开始,结束,步进(见下表)
91-
| minute-step | Number | 0 | 设置分钟的步进, 设置大于0不显示秒的选择(0-60)
92-
| first-day-of-week | Number | 7 | 设置日历星期几开头(1-7)
93-
| input-class | String | 'mx-input' | 自定义输入框的类名
94-
| input-name | String | 'date' | 自定义input 的 name 属性
95-
| confirm-text | String | 'OK' | 确认按钮的名称
96-
| range-separator | String | '~' | range 分隔符
97-
| date-format | String | '' | 格式化时间组件头部和日历的tooltip,默认是format字段去除时间的格式化
72+
| 属性 | 类型 | 可选值 | 默认值 | 描述
73+
|---------------------|---------------| ---------------------- |-------------| -----------
74+
| type | String | date,datetime,year,month,time | 'date' | 选择日期或日期时间
75+
| range | Boolean | - | false | 如果是true, 显示日历范围选择
76+
| format | String | - | YYYY-MM-DD | 格式化显示日期 api类似moment.js
77+
| value-type | String/Object | date/format/timestamp | 'date' | 设置绑定值的格式([详情](#value-type)) |
78+
| lang | String/Object | en/zh/es/pt-br/fr/ru/de/it/cs| zh | 选择语言或自定义 ([自定义](#lang))
79+
| clearable | Boolean | - | true | 如果设置false, 不显示清除图标
80+
| confirm | Boolean | - | false | 如果是true, 显示确认按钮且需要确认才更新时间
81+
| editable | Boolean | - | true | 如果是false, 用户不能手动输入更新日期
82+
| disabled | Boolean | - | false | 禁用组件
83+
| placeholder | String | - | | 输入框placeholder
84+
| width | String/Number | - | 210 | 设置宽度
85+
| append-to-body | Boolean | - | false | 弹出层放到body下面
86+
| popup-style | Object | - | | 弹出层的样式(可以覆盖left,top样式)
87+
| not-before | String/Date | - | '' | 禁止选择这个时间之前的时间
88+
| not-after | String/Date | - | '' | 禁止选择这个时间之前=后的时间
89+
| disabled-days | Array/function| - | [] | 自定义禁止的日期
90+
| shortcuts | Boolean/Array | - | true | 自定义范围选择的时候快捷选项(见下表)
91+
| time-picker-options | Object | - | {} | 自定义时间选择的开始,结束,步进(见下表)
92+
| minute-step | Number | 0 - 60 | 0 | 设置分钟的步进, 设置大于0不显示秒的选择(0-60)
93+
| first-day-of-week | Number | 1 - 7 | 7 | 设置日历星期几开头
94+
| input-class | String | - | 'mx-input' | 自定义input元素的类名
95+
| input-attr | Object | — | | 自定义input元是的属性(eg: { required: true, id: 'input', name:'date'})
96+
| confirm-text | String | - | 'OK' | 确认按钮的名称
97+
| range-separator | String | - | '~' | range 分隔符
98+
| date-format | String | - | '' | 格式化时间组件头部和日历的tooltip,默认是format字段去除时间的格式化
99+
100+
101+
#### value-type
102+
设置绑定值的格式
103+
104+
| 可选值 | 描述
105+
|-----------------|---------------------------------------
106+
| date | 返回的绑定值是Date对象
107+
| timestamp | 返回的绑定值是时间戳数字
108+
| format | 返回的绑定值是通过`format`属性格式化的值
109+
110+
高级: 也可以传入一个自定义实现包含2个函数的对象
111+
```js
112+
{
113+
value2date: (value: any) => Date, // 转化绑定值到日历时间对象
114+
date2value: (date: Date) => any // 转化日历时间对象到绑定值
115+
}
116+
117+
```
98118

99119
#### lang
100120
* String (en/zh/es/pt-br/fr/ru/de/it/cs)

src/index.vue

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
import fecha from 'fecha'
110110
import clickoutside from '@/directives/clickoutside'
111111
import { isValidDate, isValidRange, isDateObejct, isPlainObject, formatDate, parseDate, throttle } from '@/utils/index'
112+
import { transformDate, transformDateRange } from '@/utils/transform'
112113
import CalendarPanel from './calendar.vue'
113114
import locale from '@/mixins/locale'
114115
import Languages from '@/locale/languages'
@@ -123,6 +124,12 @@ export default {
123124
},
124125
props: {
125126
value: null,
127+
valueType: {
128+
default: 'date',
129+
validator: function (value) {
130+
return ['timestamp', 'format', 'date'].indexOf(value) !== -1 || isPlainObject(value)
131+
}
132+
},
126133
placeholder: {
127134
type: String,
128135
default: null
@@ -217,6 +224,14 @@ export default {
217224
}
218225
},
219226
computed: {
227+
transform () {
228+
const obj = this.range ? transformDateRange : transformDate
229+
const type = this.valueType
230+
if (isPlainObject(type)) {
231+
return { ...obj.date, ...type }
232+
}
233+
return obj[type] || obj.date
234+
},
220235
language () {
221236
if (isPlainObject(this.lang)) {
222237
return { ...Languages.en, ...this.lang }
@@ -233,11 +248,12 @@ export default {
233248
if (this.userInput !== null) {
234249
return this.userInput
235250
}
251+
const date = this.transform.value2date(this.value, this.format)
236252
if (!this.range) {
237-
return isValidDate(this.value) ? this.stringify(this.value) : ''
253+
return date ? this.stringify(date) : ''
238254
}
239-
return isValidRange(this.value)
240-
? `${this.stringify(this.value[0])} ${this.rangeSeparator} ${this.stringify(this.value[1])}`
255+
return Array.isArray(date) && date[0] && date[1]
256+
? `${this.stringify(date[0])} ${this.rangeSeparator} ${this.stringify(date[1])}`
241257
: ''
242258
},
243259
computedWidth () {
@@ -264,28 +280,28 @@ export default {
264280
{
265281
text: pickers[0],
266282
onClick (self) {
267-
self.currentValue = [ new Date(), new Date(Date.now() + 3600 * 1000 * 24 * 7) ]
283+
self.currentValue = [new Date(), new Date(Date.now() + 3600 * 1000 * 24 * 7)]
268284
self.updateDate(true)
269285
}
270286
},
271287
{
272288
text: pickers[1],
273289
onClick (self) {
274-
self.currentValue = [ new Date(), new Date(Date.now() + 3600 * 1000 * 24 * 30) ]
290+
self.currentValue = [new Date(), new Date(Date.now() + 3600 * 1000 * 24 * 30)]
275291
self.updateDate(true)
276292
}
277293
},
278294
{
279295
text: pickers[2],
280296
onClick (self) {
281-
self.currentValue = [ new Date(Date.now() - 3600 * 1000 * 24 * 7), new Date() ]
297+
self.currentValue = [new Date(Date.now() - 3600 * 1000 * 24 * 7), new Date()]
282298
self.updateDate(true)
283299
}
284300
},
285301
{
286302
text: pickers[3],
287303
onClick (self) {
288-
self.currentValue = [ new Date(Date.now() - 3600 * 1000 * 24 * 30), new Date() ]
304+
self.currentValue = [new Date(Date.now() - 3600 * 1000 * 24 * 30), new Date()]
289305
self.updateDate(true)
290306
}
291307
}
@@ -346,7 +362,7 @@ export default {
346362
if (typeof range.onClick === 'function') {
347363
return range.onClick(this)
348364
}
349-
this.currentValue = [ new Date(range.start), new Date(range.end) ]
365+
this.currentValue = [new Date(range.start), new Date(range.end)]
350366
this.updateDate(true)
351367
},
352368
clearDate () {
@@ -360,7 +376,7 @@ export default {
360376
if (valid) {
361377
this.updateDate(true)
362378
}
363-
this.$emit('confirm', this.currentValue)
379+
this.emitDate('confirm')
364380
this.closePopup()
365381
},
366382
updateDate (confirm = false) {
@@ -371,16 +387,15 @@ export default {
371387
if (equal) {
372388
return false
373389
}
374-
this.$emit('input', this.currentValue)
375-
this.$emit('change', this.currentValue)
390+
this.emitDate('input')
391+
this.emitDate('change')
376392
return true
377393
},
394+
emitDate (eventName) {
395+
this.$emit(eventName, this.transform.date2value(this.currentValue, this.format))
396+
},
378397
handleValueChange (value) {
379-
if (!this.range) {
380-
this.currentValue = isValidDate(value) ? new Date(value) : null
381-
} else {
382-
this.currentValue = isValidRange(value) ? [new Date(value[0]), new Date(value[1])] : [null, null]
383-
}
398+
this.currentValue = this.transform.value2date(value, this.format)
384399
},
385400
selectDate (date) {
386401
this.currentValue = date
@@ -484,7 +499,7 @@ export default {
484499
const start = this.parseDate(range[0], this.format)
485500
const end = this.parseDate(range[1], this.format)
486501
if (start && end && !checkDate(start, null, end) && !checkDate(end, start, null)) {
487-
this.currentValue = [ start, end ]
502+
this.currentValue = [start, end]
488503
this.updateDate(true)
489504
this.closePopup()
490505
return

src/utils/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export function parseDate (value, format) {
6666
try {
6767
return fecha.parse(value, format)
6868
} catch (e) {
69-
return false
69+
return null
7070
}
7171
}
7272

0 commit comments

Comments
 (0)