mirror of
https://github.com/tenrok/vue2-datepicker.git
synced 2026-05-30 09:14:06 +03:00
feat: support custom format function
This commit is contained in:
@@ -85,7 +85,7 @@ export default {
|
||||
|------|--------------|-------|---------|
|
||||
| type | select date type | 'date' \| 'datetime' \| 'year' \| 'month' \| 'time' | 'date' |
|
||||
| range | if true, the type is daterange or datetimerange | `boolean` | false |
|
||||
| format | format the Date. The parsing tokens are similar to the moment.js | [token](https://github.com/taylorhakes/fecha#formatting-tokens) | 'YYYY-MM-DD' |
|
||||
| format | format the Date. The parsing tokens are similar to the moment.js | [token](https://github.com/taylorhakes/fecha#formatting-tokens) \| [`object`](https://github.com/mengxiong10/vue2-datepicker/issues/232#issuecomment-458558141) | 'YYYY-MM-DD' |
|
||||
| value-type | type of binding value. If not specified, the binding value will be a Date object | [value-type](#value-type) | 'date' |
|
||||
| lang | Translation | [lang](#lang) | 'zh' |
|
||||
| clearable | if false, don't show the clear icon | `boolean` | true |
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ export default {
|
||||
|------|--------------|-------|---------|
|
||||
| type | 选择日期类型 | 'date' \| 'datetime' \| 'year' \| 'month' \| 'time' | 'date' |
|
||||
| range | 如果是true, 显示日历范围选择 | `boolean` | false |
|
||||
| format | 格式化显示日期, 值类似moment.js | [token](https://github.com/taylorhakes/fecha#formatting-tokens) | 'YYYY-MM-DD' |
|
||||
| format | 格式化显示日期, 值类似moment.js | [token](https://github.com/taylorhakes/fecha#formatting-tokens) \| [`object`](https://github.com/mengxiong10/vue2-datepicker/issues/232#issuecomment-458558141) | 'YYYY-MM-DD' |
|
||||
| value-type | 设置绑定值的格式, 默认返回日期对象 | [value-type](#value-type) | 'date' |
|
||||
| lang | 选择语言或自定义 | [lang](#lang) | 'zh' |
|
||||
| clearable | 如果设置false, 不显示清除图标 | `boolean` | true |
|
||||
|
||||
+53
-21
@@ -110,8 +110,8 @@
|
||||
<script>
|
||||
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 { isValidDate, isValidRangeDate, isDateObejct, isPlainObject, formatDate, parseDate, throttle } from '@/utils/index'
|
||||
import { transformDate } from '@/utils/transform'
|
||||
import CalendarPanel from './calendar.vue'
|
||||
import locale from '@/mixins/locale'
|
||||
import Languages from '@/locale/languages'
|
||||
@@ -141,7 +141,7 @@ export default {
|
||||
default: 'zh'
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
type: [String, Object],
|
||||
default: 'YYYY-MM-DD'
|
||||
},
|
||||
dateFormat: {
|
||||
@@ -227,12 +227,17 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
transform () {
|
||||
const obj = this.range ? transformDateRange : transformDate
|
||||
const type = this.valueType
|
||||
if (isPlainObject(type)) {
|
||||
return { ...obj.date, ...type }
|
||||
return { ...transformDate.date, ...type }
|
||||
}
|
||||
return obj[type] || obj.date
|
||||
if (type === 'format') {
|
||||
return {
|
||||
value2date: this.parse.bind(this),
|
||||
date2value: this.stringify.bind(this)
|
||||
}
|
||||
}
|
||||
return transformDate[type] || transformDate.date
|
||||
},
|
||||
language () {
|
||||
if (isPlainObject(this.lang)) {
|
||||
@@ -250,12 +255,14 @@ export default {
|
||||
if (this.userInput !== null) {
|
||||
return this.userInput
|
||||
}
|
||||
const date = this.transform.value2date(this.value, this.format)
|
||||
const { value2date } = this.transform
|
||||
if (!this.range) {
|
||||
return date ? this.stringify(date) : ''
|
||||
return this.isValidValue(this.value)
|
||||
? this.stringify(value2date(this.value))
|
||||
: ''
|
||||
}
|
||||
return Array.isArray(date) && date[0] && date[1]
|
||||
? `${this.stringify(date[0])} ${this.rangeSeparator} ${this.stringify(date[1])}`
|
||||
return this.isValidRangeValue(this.value)
|
||||
? `${this.stringify(value2date(this.value[0]))} ${this.rangeSeparator} ${this.stringify(value2date(this.value[1]))}`
|
||||
: ''
|
||||
},
|
||||
computedWidth () {
|
||||
@@ -265,7 +272,7 @@ export default {
|
||||
return this.width
|
||||
},
|
||||
showClearIcon () {
|
||||
return !this.disabled && this.clearable && (this.range ? isValidRange(this.value) : isValidDate(this.value))
|
||||
return !this.disabled && this.clearable && (this.range ? this.isValidRangeValue(this.value) : this.isValidValue(this.value))
|
||||
},
|
||||
innerType () {
|
||||
return String(this.type).toLowerCase()
|
||||
@@ -314,6 +321,9 @@ export default {
|
||||
if (this.dateFormat) {
|
||||
return this.dateFormat
|
||||
}
|
||||
if (typeof this.format !== 'string') {
|
||||
return 'YYYY-MM-DD'
|
||||
}
|
||||
if (this.innerType === 'date') {
|
||||
return this.format
|
||||
}
|
||||
@@ -348,11 +358,24 @@ export default {
|
||||
this.handleValueChange(this.value)
|
||||
this.displayPopup()
|
||||
},
|
||||
stringify (date, format) {
|
||||
return formatDate(date, format || this.format)
|
||||
stringify (date) {
|
||||
return (isPlainObject(this.format) && typeof this.format.stringify === 'function')
|
||||
? this.format.stringify(date)
|
||||
: formatDate(date, this.format)
|
||||
},
|
||||
parseDate (value, format) {
|
||||
return parseDate(value, format || this.format)
|
||||
parse (value) {
|
||||
return (isPlainObject(this.format) && typeof this.format.parse === 'function')
|
||||
? this.format.parse(value)
|
||||
: parseDate(value, this.format)
|
||||
},
|
||||
isValidValue (value) {
|
||||
const { value2date } = this.transform
|
||||
return isValidDate(value2date(value))
|
||||
},
|
||||
isValidRangeValue (value) {
|
||||
const { value2date } = this.transform
|
||||
return Array.isArray(value) && value.length === 2 && this.isValidValue(value[0]) &&
|
||||
this.isValidValue(value[1]) && (value2date(value[1]).getTime() >= value2date(value[0]).getTime())
|
||||
},
|
||||
dateEqual (a, b) {
|
||||
return isDateObejct(a) && isDateObejct(b) && a.getTime() === b.getTime()
|
||||
@@ -374,7 +397,7 @@ export default {
|
||||
this.$emit('clear')
|
||||
},
|
||||
confirmDate () {
|
||||
const valid = this.range ? isValidRange(this.currentValue) : isValidDate(this.currentValue)
|
||||
const valid = this.range ? isValidRangeDate(this.currentValue) : isValidDate(this.currentValue)
|
||||
if (valid) {
|
||||
this.updateDate(true)
|
||||
}
|
||||
@@ -394,10 +417,19 @@ export default {
|
||||
return true
|
||||
},
|
||||
emitDate (eventName) {
|
||||
this.$emit(eventName, this.transform.date2value(this.currentValue, this.format))
|
||||
const { date2value } = this.transform
|
||||
const value = this.range
|
||||
? this.currentValue.map(date2value)
|
||||
: date2value(this.currentValue)
|
||||
this.$emit(eventName, value)
|
||||
},
|
||||
handleValueChange (value) {
|
||||
this.currentValue = this.transform.value2date(value, this.format)
|
||||
const { value2date } = this.transform
|
||||
if (this.range) {
|
||||
this.currentValue = this.isValidRangeValue(value) ? value.map(value2date) : [null, null]
|
||||
} else {
|
||||
this.currentValue = this.isValidValue(value) ? value2date(value) : null
|
||||
}
|
||||
},
|
||||
selectDate (date) {
|
||||
this.currentValue = date
|
||||
@@ -497,8 +529,8 @@ export default {
|
||||
if (this.range) {
|
||||
const range = value.split(` ${this.rangeSeparator} `)
|
||||
if (range.length === 2) {
|
||||
const start = this.parseDate(range[0], this.format)
|
||||
const end = this.parseDate(range[1], this.format)
|
||||
const start = this.parse(range[0])
|
||||
const end = this.parse(range[1])
|
||||
if (start && end && !checkDate(start, null, end) && !checkDate(end, start, null)) {
|
||||
this.currentValue = [start, end]
|
||||
this.updateDate(true)
|
||||
@@ -507,7 +539,7 @@ export default {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const date = this.parseDate(value, this.format)
|
||||
const date = this.parse(value)
|
||||
if (date && !checkDate(date, null, null)) {
|
||||
this.currentValue = date
|
||||
this.updateDate(true)
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ export function isValidDate (date) {
|
||||
return !isNaN(new Date(date).getTime())
|
||||
}
|
||||
|
||||
export function isValidRange (date) {
|
||||
export function isValidRangeDate (date) {
|
||||
return (
|
||||
Array.isArray(date) &&
|
||||
date.length === 2 &&
|
||||
|
||||
+2
-30
@@ -1,4 +1,4 @@
|
||||
import { isValidDate, isValidRange, parseDate, formatDate } from './index'
|
||||
import { isValidDate } from './index'
|
||||
|
||||
export const transformDate = {
|
||||
date: {
|
||||
@@ -7,34 +7,6 @@ export const transformDate = {
|
||||
},
|
||||
timestamp: {
|
||||
value2date: (value) => isValidDate(value) ? new Date(value) : null,
|
||||
date2value: (date) => isValidDate(date) ? new Date(date).getTime() : null
|
||||
},
|
||||
format: {
|
||||
value2date: parseDate,
|
||||
date2value: (date, format) => isValidDate(date) ? formatDate(date, format) : null
|
||||
}
|
||||
}
|
||||
|
||||
export const transformDateRange = {
|
||||
date: {
|
||||
value2date: (value) => isValidRange(value) ? [new Date(value[0]), new Date(value[1])] : [null, null],
|
||||
date2value: (date) => date
|
||||
},
|
||||
timestamp: {
|
||||
value2date: (value) => isValidRange(value) ? [new Date(value[0]), new Date(value[1])] : [null, null],
|
||||
date2value: (date) => date.map(transformDate.timestamp.date2value)
|
||||
},
|
||||
format: {
|
||||
value2date: (value, format) => {
|
||||
if (Array.isArray(value) && value.length === 2) {
|
||||
const value0 = parseDate(value[0], format)
|
||||
const value1 = parseDate(value[1], format)
|
||||
if (value0 && value1 && value1 >= value0) {
|
||||
return [value0, value1]
|
||||
}
|
||||
}
|
||||
return [null, null]
|
||||
},
|
||||
date2value: (date, format) => date.map(v => transformDate.format.date2value(v, format))
|
||||
date2value: (date) => date && new Date(date).getTime()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-10
@@ -5,7 +5,7 @@ import CalendarPanel from '../src/calendar.vue'
|
||||
import DatePanel from '../src/panel/date'
|
||||
import TimePanel from '../src/panel/time'
|
||||
import YearPanel from '../src/panel/year'
|
||||
import { transformDate, transformDateRange } from '../src/utils/transform'
|
||||
import { transformDate } from '../src/utils/transform'
|
||||
|
||||
let wrapper
|
||||
|
||||
@@ -24,15 +24,6 @@ describe('datepicker', () => {
|
||||
expect(vm.transform).toBe(transformDate.date)
|
||||
wrapper.setProps({ valueType: 'timestamp' })
|
||||
expect(vm.transform).toBe(transformDate.timestamp)
|
||||
wrapper.setProps({ valueType: 'format' })
|
||||
expect(vm.transform).toBe(transformDate.format)
|
||||
|
||||
wrapper.setProps({ valueType: 'date', range: true })
|
||||
expect(vm.transform).toBe(transformDateRange.date)
|
||||
wrapper.setProps({ valueType: 'timestamp' })
|
||||
expect(vm.transform).toBe(transformDateRange.timestamp)
|
||||
wrapper.setProps({ valueType: 'format' })
|
||||
expect(vm.transform).toBe(transformDateRange.format)
|
||||
|
||||
const fn = (date) => date
|
||||
wrapper.setProps({ valueType: {
|
||||
|
||||
+7
-18
@@ -1,29 +1,18 @@
|
||||
import { transformDate, transformDateRange } from '../src/utils/transform'
|
||||
import { transformDate } from '../src/utils/transform'
|
||||
|
||||
const time = new Date(2019, 1, 3)
|
||||
const timestamp = time.getTime()
|
||||
const format = 'MM-DD-YYYY'
|
||||
const text = '02-03-2019'
|
||||
|
||||
const testfn = ({ type, value, date, err = null, range = false }) => it(`${type}}`, () => {
|
||||
const obj = range ? transformDateRange : transformDate
|
||||
const testfn = ({ type, value, date, err = null }) => it(`${type}}`, () => {
|
||||
const obj = transformDate
|
||||
const typeObj = obj[type]
|
||||
expect(typeObj.value2date(err, format)).toEqual(err)
|
||||
expect(typeObj.value2date(value, format)).toEqual(date)
|
||||
expect(typeObj.date2value(err, format)).toEqual(err)
|
||||
expect(typeObj.date2value(date, format)).toEqual(value)
|
||||
expect(typeObj.value2date(err)).toEqual(err)
|
||||
expect(typeObj.value2date(value)).toEqual(date)
|
||||
expect(typeObj.date2value(err)).toEqual(err)
|
||||
expect(typeObj.date2value(date)).toEqual(value)
|
||||
})
|
||||
|
||||
describe('transformDate', () => {
|
||||
testfn({ type: 'date', value: time, date: time })
|
||||
testfn({ type: 'format', value: text, date: time })
|
||||
testfn({ type: 'timestamp', value: timestamp, date: time })
|
||||
})
|
||||
|
||||
describe('transformDateRange', () => {
|
||||
const err = [null, null]
|
||||
const date = [time, time]
|
||||
testfn({ type: 'date', value: [time, time], date, err, range: true })
|
||||
testfn({ type: 'format', value: [text, text], date, err, range: true })
|
||||
testfn({ type: 'timestamp', value: [timestamp, timestamp], date, err, range: true })
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user