@prettyy/ui
Version:
vue2 UI
308 lines (285 loc) • 8.41 kB
JavaScript
import RangeLayout from "../../lib/picker/src/RangeLayout.vue"
import Picker from "../../lib/picker/src/main.vue"
import Popper from "../../lib/date-picker/src/Popper.vue"
import ClearButton from "../../lib/date-picker/src/ClearButton.vue"
import Shortcuts from "../../lib/date-picker/src/Shortcuts.vue"
export default {
components: { RangeLayout, Picker, Popper },
data() {
return {
h: null,
c: null,
hideTimerHandle: -1
}
},
computed: {
valueSlot() {
return this.$slots.value || this.$scopedSlots.value
}
},
methods: {
renderValueSlot() {
if (!this.valueSlot) {
return null
}
return this.$slots.value || this.$scopedSlots.value({
type: this.type,
format: this.finalFormat,
value: this.value,
visible: this.isVisible
})
},
renderLayout(begin, end) {
const slots = {}
let prependContent
let appendContent
if (this.clearable) {
appendContent = this.renderClearButton(this.clearRangeValue)
}
if (this.isIconVisible) {
prependContent = this.renderIcon()
}
slots.begin = () => [begin]
slots.end = () => [end]
if (prependContent) {
slots.prepend = () => prependContent
}
if (appendContent) {
slots.append = () => appendContent
}
return this.h(RangeLayout, {
props: {
showClear: this.isClearVisible
},
scopedSlots: slots
})
},
renderClearButton(handler) {
return this.h(ClearButton, {
on: {
clear: () => {
this._eventSrc = 'clear'
this.isVisible = false
handler()
}
}
})
},
/**
* 渲染 input 输入框
* @param {string} valueName
* @param {string} [placeholder]
* @return {*|void}
*/
renderInput(valueName, placeholder) {
return this.h('span', {
attrs: {
class: 'vl-date-picker--value-wrapper'
}
}, [this.h('input', {
attrs: {
type: 'text',
value: this[valueName],
readonly: !this.allowEdit,
disabled: 'disabled',
placeholder,
tabindex: -1
},
on: {
input: e => {
this[valueName] = e.target.value
}
}
})])
},
/**
*
* @param {Object}content
* @param {Object}trigger
* @return {*}
*/
renderPopper(content, trigger) {
const h = this.h
const slots = Array.isArray(content) ? content : [content]
if (this.$slots.shortcut || this.shortcuts.length) {
slots.unshift(this.renderShortcuts(this.$slots.shortcut))
}
return h(Popper, {
props: {
visible: this.readonly ? false : this.isVisible,
popperClass: this.popperClass,
valueClass: this.valueClass,
toBody: this.toBody,
options: this.popperOptions
},
ref: 'popper',
on: {
blur: this.onBlur
},
scopedSlots: {
default: () => slots,
reference: () => {
return [trigger]
},
footer: () => this.$slots.footer
}
})
},
renderShortcuts(content) {
const options = {
props: {
data: this.shortcuts
},
on: {
change: ({ value }) => {
this._eventSrc = 'shortcut'
this.updateValue(value)
}
}
}
if (content && content.length) {
return this.h(Shortcuts, options, Array.isArray(content) ? content : [content])
}
return this.h(Shortcuts, options)
},
/**
*
* @param valueName
* @param visibleName
* @param limitName
* @param {null|HTMLElement} titleSlot
* @param {boolean} [doNotAutoClose=false]
* @returns {*|void}
*/
renderPicker(valueName, visibleName, limitName, titleSlot, doNotAutoClose) {
const props = {
format: this.finalFormat,
value: this[valueName],
type: this.type,
readonly: this.readonly,
size: this.size,
min: this[limitName][0],
max: this[limitName][1],
visible: this[visibleName],
mousewheel: this.mousewheel,
weekStart: this.weekStart,
showLunar: this.showLunar,
showFestival: this.showFestival,
markFunction: this.markFunction
}
if (this.highlightRange && this.isRange) {
props.highlightRange = [this.beginValue, this.endValue]
}
const option = {
props,
on: {
input: value => {
this._eventSrc = 'picker'
this[valueName] = value
},
change: () => {
if (doNotAutoClose || this.type === this.types.DATETIME || this.type === this.types.TIME) {
return
}
this[visibleName] = false
}
}
}
if (titleSlot) {
option.scopedSlots = {
title: () => titleSlot
}
}
return this.h(Picker, option)
},
renderRange() {
const content = [
this.renderPicker('beginValue', 'isVisible', 'rangeBeginLimit', this.rangeBeginTitle, true),
this.renderPicker('endValue', 'isVisible', 'rangeEndLimit', this.rangeEndTitle, true)
]
return this.renderPopper(
content,
this.renderValueSlot() || this.renderLayout(
this.renderInput('formattedBeginValue', this.placeholderBeginText),
this.renderInput('formattedEndValue', this.placeholderEndText)
)
)
},
// 针对季度与周单独渲染
renderSpecialPicker() {
return this.renderPopper(
this.renderPicker('beginValue', 'isVisible', 'singleLimit', this.singleTitle),
this.renderValueSlot() || this.renderLayout(
this.renderInput('formattedBeginValue', this.placeholderText),
this.renderInput('formattedEndValue')
)
)
},
// 渲染单个日期选择
renderSinglePicker() {
const content = []
if (!this.valueSlot) {
content.push(this.renderInput('formattedValue', this.placeholderText))
if (this.isIconVisible) {
content.unshift(this.renderIcon())
}
if (this.clearable) {
content.push(this.renderClearButton(this.clearSingleValue))
}
}
return this.renderPopper(
this.renderPicker('singleValue', 'isVisible', 'singleLimit', this.singleTitle),
this.renderValueSlot() || this.h('div',
{
attrs: {
'class': 'vl-date-picker--container'
}
},
content)
)
},
renderIcon() {
return this.h('span', {
attrs: {
'class': ' vl-icon vl-date-picker--icon'
}
})
},
// 判断需要渲染哪成单个日期选择还是按范围选择
renderComponent() {
if (!this.isRange) {
return this.renderSinglePicker()
}
if (this.type === this.types.WEEK || this.type === this.types.QUARTER) {
return this.renderSpecialPicker()
}
return this.renderRange()
}
},
render(createElement, context) {
this.h = createElement
this.c = context
const content = [this.renderComponent()]
return createElement('div', {
'class': {
'vl-date-picker': true,
[`vl-date-picker--${this.type}`]: true,
[`vl-date-picker--${this.size}`]: true,
'vl-date-picker--range': this.isRange,
'vl-date-picker--clearable': this.clearable,
'vl-date-picker--show-icon': this.isIconVisible,
'vl-date-picker--show-lunar': this.showLunar,
'vl-date-picker--empty': this.isEmpty,
'vl-date-picker--custom-render': this.valueSlot
},
attrs: {
tabindex: '0',
'datepicker-id': this.id
},
on: {
focus: this.onFocus,
blur: this.onBlur
}
}, content)
}
}