Skip to content

Commit

Permalink
feat: add valueType to format binding value
Browse files Browse the repository at this point in the history
  • Loading branch information
mengxiong10 committed Jan 13, 2019
1 parent 3775970 commit dd6f2ea
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 71 deletions.
71 changes: 44 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,34 +69,51 @@ export default {
```
### Props

| Prop | Type | Default | Description |
|---------------------|---------------|-------------|-----------------------------------------------------|
| type | String | 'date' | select date type (date/datetime/year/month/time) |
| range | Boolean | false | if true, the type is daterange or datetimerange |
| format | String | YYYY-MM-DD | The parsing tokens are similar to the moment.js |
| lang | String/Object | zh | Translation ([custom](#lang))(en/zh/es/pt-br/fr/ru/de/it/cs) |
| clearable | Boolean | true | if false, don't show the clear icon |
| confirm | Boolean | false | if true, need click the button to change the value |
| editable | Boolean | true | if false, user cann't type it |
| disabled | Boolean | false | Disable the component |
| placeholder | String | | input placeholder text |
| width | String/Number | 210 | input size |
| append-to-body | Boolean | false | append the popup to body |
| popupStyle | Object | | popup style(override the top, left style) |
| not-before | String/Date | '' | Disable all dates before new Date(not-before) |
| not-after | String/Date | '' | Disable all dates after new Date(not-after) |
| disabled-days | Array/function| [] | Disable Days |
| shortcuts | Boolean/Array | true | the shortcuts for the range picker |
| time-picker-options | Object | {} | set timePickerOptions(start, step, end) |
| minute-step | Number | 0 | if > 0 don't show the second picker(0 - 60) |
| first-day-of-week | Number | 7 | set the first day of week (1-7) |
| input-class | String | 'mx-input' | the input class name |
| input-name | String | 'date' | the input name attr |
| input-attr | Object | | the input attr(eg: { required: true, id: 'input'}) |
| confirm-text | String | 'OK' | the default text to display on confirm button |
| range-separator | String | '~' | the range separator text |
| date-format | String | '' | format the time header and tooltip |
| Prop | Type | Accepted Values | Default | Description |
|---------------------|---------------|-----------------|-------------|-----------------------------------------------------|
| type | String | date/datetime/year/month/time | 'date' | select date type |
| range | Boolean || false | if true, the type is daterange or datetimerange |
| format | String || YYYY-MM-DD | The parsing tokens are similar to the moment.js |
| 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)) |
| lang | String/Object | en/zh/es/pt-br/fr/ru/de/it/cs | zh | Translation (set [how to custom](#lang)) |
| clearable | Boolean || true | if false, don't show the clear icon |
| confirm | Boolean || false | if true, need click the button to change the value |
| editable | Boolean || true | if false, user cann't type it |
| disabled | Boolean || false | Disable the component |
| placeholder | String || | input placeholder text |
| width | String/Number || 210 | input size |
| append-to-body | Boolean || false | append the popup to body |
| popupStyle | Object || | popup style(override the top, left style) |
| not-before | String/Date || '' | Disable all dates before new Date(not-before) |
| not-after | String/Date || '' | Disable all dates after new Date(not-after) |
| disabled-days | Array/function|| [] | Disable Days |
| shortcuts | Boolean/Array || true | the shortcuts for the range picker |
| time-picker-options | Object || {} | set timePickerOptions(start, step, end) |
| minute-step | Number | 0 - 60 | 0 | if > 0 don't show the second picker |
| first-day-of-week | Number | 1 - 7 | 7 | set the first day of week |
| input-class | String || 'mx-input' | the input class name |
| input-attr | Object || | the input attr(eg: { required: true, id: 'input'}) |
| confirm-text | String || 'OK' | the default text to display on confirm button |
| range-separator | String || '~' | the range separator text |
| date-format | String || '' | format the time header and tooltip |

#### value-type
set the format of binding value

| Value | Description |
|-----------------|-------------------------------------------|
| date | binding value will be a Date object |
| timestamp | binding value will be a timestamp number |
| format | binding value will be the format string |

Advanced: You can also customize objects to implement two functions.
```js
{
value2date: (value: any) => Date, // transform the binding value to calendar Date Object
date2value: (date: Date) => any // transform the calendar Date Object to binding value
}

```

#### lang
* String (en/zh/es/pt-br/fr/ru/de/it/cs)
Expand Down
72 changes: 46 additions & 26 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,32 +69,52 @@ export default {
```
### Props

| Prop | Type | Default | Description
|---------------------|---------------|-------------|-----------------------------------------------------
| type | String | 'date' | 选择日期或日期时间(可选:date,datetime,year,month,time)
| range | Boolean | false | 如果是true, 显示日历范围选择
| format | String | YYYY-MM-DD | 格式化显示日期 api类似moment.js
| lang | String/Object | zh | 选择语言或自定义 (en/zh/es/pt-br/fr/ru/de/it/cs)(custom)
| clearable | Boolean | true | 如果设置false, 不显示清除图标
| confirm | Boolean | false | 如果是true, 显示确认按钮且需要确认才更新时间
| editable | Boolean | true | 如果是false, 用户不能手动输入更新日期
| disabled | Boolean | false | 禁用组件
| placeholder | String | | 输入框placeholder
| width | String/Number | 210 | 设置宽度
| append-to-body | Boolean | false | 弹出层放到body下面
| popup-style | Object | | 弹出层的样式(可以覆盖left,top样式)
| not-before | String/Date | '' | 禁止选择这个时间之前的时间
| not-after | String/Date | '' | 禁止选择这个时间之前=后的时间
| disabled-days | Array/function| [] | 自定义禁止的日期
| shortcuts | Boolean/Array | true | 自定义范围选择的时候快捷选项(见下表)
| time-picker-options | Object | {} | 自定义时间选择的开始,结束,步进(见下表)
| minute-step | Number | 0 | 设置分钟的步进, 设置大于0不显示秒的选择(0-60)
| first-day-of-week | Number | 7 | 设置日历星期几开头(1-7)
| input-class | String | 'mx-input' | 自定义输入框的类名
| input-name | String | 'date' | 自定义input 的 name 属性
| confirm-text | String | 'OK' | 确认按钮的名称
| range-separator | String | '~' | range 分隔符
| date-format | String | '' | 格式化时间组件头部和日历的tooltip,默认是format字段去除时间的格式化
| 属性 | 类型 | 可选值 | 默认值 | 描述
|---------------------|---------------| ---------------------- |-------------| -----------
| type | String | date,datetime,year,month,time | 'date' | 选择日期或日期时间
| range | Boolean | - | false | 如果是true, 显示日历范围选择
| format | String | - | YYYY-MM-DD | 格式化显示日期 api类似moment.js
| value-type | String/Object | date/format/timestamp | 'date' | 设置绑定值的格式([详情](#value-type)) |
| lang | String/Object | en/zh/es/pt-br/fr/ru/de/it/cs| zh | 选择语言或自定义 ([自定义](#lang))
| clearable | Boolean | - | true | 如果设置false, 不显示清除图标
| confirm | Boolean | - | false | 如果是true, 显示确认按钮且需要确认才更新时间
| editable | Boolean | - | true | 如果是false, 用户不能手动输入更新日期
| disabled | Boolean | - | false | 禁用组件
| placeholder | String | - | | 输入框placeholder
| width | String/Number | - | 210 | 设置宽度
| append-to-body | Boolean | - | false | 弹出层放到body下面
| popup-style | Object | - | | 弹出层的样式(可以覆盖left,top样式)
| not-before | String/Date | - | '' | 禁止选择这个时间之前的时间
| not-after | String/Date | - | '' | 禁止选择这个时间之前=后的时间
| disabled-days | Array/function| - | [] | 自定义禁止的日期
| shortcuts | Boolean/Array | - | true | 自定义范围选择的时候快捷选项(见下表)
| time-picker-options | Object | - | {} | 自定义时间选择的开始,结束,步进(见下表)
| minute-step | Number | 0 - 60 | 0 | 设置分钟的步进, 设置大于0不显示秒的选择(0-60)
| first-day-of-week | Number | 1 - 7 | 7 | 设置日历星期几开头
| input-class | String | - | 'mx-input' | 自定义input元素的类名
| input-attr | Object | — | | 自定义input元是的属性(eg: { required: true, id: 'input', name:'date'})
| confirm-text | String | - | 'OK' | 确认按钮的名称
| range-separator | String | - | '~' | range 分隔符
| date-format | String | - | '' | 格式化时间组件头部和日历的tooltip,默认是format字段去除时间的格式化


#### value-type
设置绑定值的格式

| 可选值 | 描述
|-----------------|---------------------------------------
| date | 返回的绑定值是Date对象
| timestamp | 返回的绑定值是时间戳数字
| format | 返回的绑定值是通过`format`属性格式化的值

高级: 也可以传入一个自定义实现包含2个函数的对象
```js
{
value2date: (value: any) => Date, // 转化绑定值到日历时间对象
date2value: (date: Date) => any // 转化日历时间对象到绑定值
}

```

#### lang
* String (en/zh/es/pt-br/fr/ru/de/it/cs)
Expand Down
49 changes: 32 additions & 17 deletions src/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
import fecha from 'fecha'
import clickoutside from '@/directives/clickoutside'
import { isValidDate, isValidRange, isDateObejct, isPlainObject, formatDate, parseDate, throttle } from '@/utils/index'
import { transformDate, transformDateRange } from '@/utils/transform'
import CalendarPanel from './calendar.vue'
import locale from '@/mixins/locale'
import Languages from '@/locale/languages'
Expand All @@ -123,6 +124,12 @@ export default {
},
props: {
value: null,
valueType: {
default: 'date',
validator: function (value) {
return ['timestamp', 'format', 'date'].indexOf(value) !== -1 || isPlainObject(value)
}
},
placeholder: {
type: String,
default: null
Expand Down Expand Up @@ -217,6 +224,14 @@ export default {
}
},
computed: {
transform () {
const obj = this.range ? transformDateRange : transformDate
const type = this.valueType
if (isPlainObject(type)) {
return { ...obj.date, ...type }
}
return obj[type] || obj.date
},
language () {
if (isPlainObject(this.lang)) {
return { ...Languages.en, ...this.lang }
Expand All @@ -233,11 +248,12 @@ export default {
if (this.userInput !== null) {
return this.userInput
}
const date = this.transform.value2date(this.value, this.format)
if (!this.range) {
return isValidDate(this.value) ? this.stringify(this.value) : ''
return date ? this.stringify(date) : ''
}
return isValidRange(this.value)
? `${this.stringify(this.value[0])} ${this.rangeSeparator} ${this.stringify(this.value[1])}`
return Array.isArray(date) && date[0] && date[1]
? `${this.stringify(date[0])} ${this.rangeSeparator} ${this.stringify(date[1])}`
: ''
},
computedWidth () {
Expand All @@ -264,28 +280,28 @@ export default {
{
text: pickers[0],
onClick (self) {
self.currentValue = [ new Date(), new Date(Date.now() + 3600 * 1000 * 24 * 7) ]
self.currentValue = [new Date(), new Date(Date.now() + 3600 * 1000 * 24 * 7)]
self.updateDate(true)
}
},
{
text: pickers[1],
onClick (self) {
self.currentValue = [ new Date(), new Date(Date.now() + 3600 * 1000 * 24 * 30) ]
self.currentValue = [new Date(), new Date(Date.now() + 3600 * 1000 * 24 * 30)]
self.updateDate(true)
}
},
{
text: pickers[2],
onClick (self) {
self.currentValue = [ new Date(Date.now() - 3600 * 1000 * 24 * 7), new Date() ]
self.currentValue = [new Date(Date.now() - 3600 * 1000 * 24 * 7), new Date()]
self.updateDate(true)
}
},
{
text: pickers[3],
onClick (self) {
self.currentValue = [ new Date(Date.now() - 3600 * 1000 * 24 * 30), new Date() ]
self.currentValue = [new Date(Date.now() - 3600 * 1000 * 24 * 30), new Date()]
self.updateDate(true)
}
}
Expand Down Expand Up @@ -346,7 +362,7 @@ export default {
if (typeof range.onClick === 'function') {
return range.onClick(this)
}
this.currentValue = [ new Date(range.start), new Date(range.end) ]
this.currentValue = [new Date(range.start), new Date(range.end)]
this.updateDate(true)
},
clearDate () {
Expand All @@ -360,7 +376,7 @@ export default {
if (valid) {
this.updateDate(true)
}
this.$emit('confirm', this.currentValue)
this.emitDate('confirm')
this.closePopup()
},
updateDate (confirm = false) {
Expand All @@ -371,16 +387,15 @@ export default {
if (equal) {
return false
}
this.$emit('input', this.currentValue)
this.$emit('change', this.currentValue)
this.emitDate('input')
this.emitDate('change')
return true
},
emitDate (eventName) {
this.$emit(eventName, this.transform.date2value(this.currentValue, this.format))
},
handleValueChange (value) {
if (!this.range) {
this.currentValue = isValidDate(value) ? new Date(value) : null
} else {
this.currentValue = isValidRange(value) ? [new Date(value[0]), new Date(value[1])] : [null, null]
}
this.currentValue = this.transform.value2date(value, this.format)
},
selectDate (date) {
this.currentValue = date
Expand Down Expand Up @@ -484,7 +499,7 @@ export default {
const start = this.parseDate(range[0], this.format)
const end = this.parseDate(range[1], this.format)
if (start && end && !checkDate(start, null, end) && !checkDate(end, start, null)) {
this.currentValue = [ start, end ]
this.currentValue = [start, end]
this.updateDate(true)
this.closePopup()
return
Expand Down
2 changes: 1 addition & 1 deletion src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function parseDate (value, format) {
try {
return fecha.parse(value, format)
} catch (e) {
return false
return null
}
}

Expand Down
Loading

0 comments on commit dd6f2ea

Please sign in to comment.