magiccube-vue3
Version:
vue3-js版组件库
175 lines (153 loc) • 5.29 kB
JavaScript
import { ref, computed, getCurrentInstance } from 'vue'
import getFormValidMethod from '../../utils/form-valid'
import { fmtValueToDate, fmtOutputValue } from './common'
import Picker from './picker'
import Dropdown from '../../utils/dropdown'
import Inner from './inner'
const DatePicker = {
name: 'McDatePicker',
props: {
modelValue: [String, Array],
/**
* default: 单日历
* range: 双日历
*/
type: {
type: String,
default: 'default'
},
placeholder: {
type: String,
default: '选择时间'
},
startPlaceholder: {
type: String,
default: '开始时间'
},
endPlaceholder: {
type: String,
default: '结束时间'
},
/**
* 结果输出和展示的日期格式
*/
format: {
type: String,
default: 'YYYY-MM-DD'
},
/** 多选设置只会在 非range的模式下启用 */
multi: Boolean,
/** 设置可选择的日历范围 可单独设置 */
enableStart: String,
enableEnd: String,
disabled: Boolean,
separator: {
type: String,
default: '至'
},
errorStatus: Boolean,
size: {
type: String,
default: 'normal'
}
},
emits: ['update:modelValue', 'change'],
setup(props, { emit }) {
const mainEl = ref(null)
const dropdownEl = ref(null)
const innerEl = ref(null)
const slide = ref(false)
/** form校验所用参数 */
const instance = getCurrentInstance()
const { fieldName, validator, errorMessage } = getFormValidMethod(instance)
const fieldError = computed(() => {
return fieldName && errorMessage?.value ? errorMessage.value[fieldName] : ''
})
const model = computed({
get() {
if (Array.isArray(props.modelValue)) {
return props.modelValue.map(n => fmtValueToDate(n, props.format))
} else if (typeof props.modelValue === 'string') {
return [fmtValueToDate(props.modelValue, props.format)]
} else {
return []
}
},
set(value) {
const _val = value.map(n => fmtOutputValue(n, props.format))
emit('update:modelValue', _val)
emit('change', _val)
validator && validator('change', _val)
}
})
const handleInput = (value) => {
setSlideUp()
model.value = value
}
const setSlideDown = (event) => {
if (innerEl?.value && dropdownEl?.value) {
const options = {
event,
pickerHeight: mainEl.value.offsetHeight,
pickerWidth: props.type === 'range' ? 500 : 250,
dropdownHeight: innerEl.value.offsetHeight || props.downMenuHeight || 310,
fixedWidth: true
}
innerEl.value.set()
dropdownEl.value.visible(options)
}
}
const setSlideUp = () => {
dropdownEl?.value && dropdownEl.value.invisible()
innerEl?.value && innerEl.value.reset()
}
const handleShowDropdown = (e) => {
if(props.disabled) return false
if (slide.value) {
setSlideUp(e)
} else {
setSlideDown(e)
}
}
const handleChange = (value) => {
model.value = value
setSlideUp()
}
return () => (
<div class="mc-date" ref={mainEl}>
<Picker data={model.value}
{...props}
format={props.format}
type={props.type}
multi={props.multi}
size={props.size}
disabled={props.disabled}
errorHint={fieldError.value}
errorStatus={props.errorStatus}
separator={props.separator}
placeholder={props.placeholder}
startPlaceholder={props.startPlaceholder}
endPlaceholder={props.endPlaceholder}
onClickPicker={handleShowDropdown}
onChange={handleInput} />
<Dropdown
ref={dropdownEl}
picker={mainEl.value}
onClose={setSlideUp}>
<Inner ref={innerEl}
data={model.value}
type={props.type}
enableStart={props.enableStart}
enableEnd={props.enableEnd}
multi={props.multi}
onChange={handleChange} />
</Dropdown>
</div>
)
}
}
DatePicker.install = Vue => {
Vue.component(DatePicker.name, DatePicker)
}
const McDatePicker = DatePicker
export { McDatePicker, McDatePicker as default }