magiccube-vue3
Version:
vue3-js版组件库
184 lines (160 loc) • 5.48 kB
JavaScript
import { ref, reactive, computed, getCurrentInstance } from 'vue'
import Dropdown from '../../utils/dropdown'
import Picker from './picker'
import Inner from './inner'
import getFormValidMethod from '../../utils/form-valid'
import * as utils from '../../utils/common'
const MonthPicker = {
name: 'McMonthPicker',
props: {
modelValue: [String, Array, null],
/**
* 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'
},
/** 多选设置只会在 非range的模式下启用 */
multi: Boolean,
/** 设置可选择的日历范围 可单独设置 */
enableStart: String,
enableEnd: String,
disabled: Boolean,
separator: {
type: String,
default: '至'
},
clear: Boolean,
},
emits: ['update:modelValue', 'change'],
setup(props, { emit }) {
const pickerEl = ref(null)
const dropdownEl = ref(null)
const innerEl = ref(null)
const state = reactive({
slide: 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)) {
const arr = props.modelValue.map(n => fmtMonthToDate(n))
return arr
} else if (typeof props.modelValue === 'string') {
return [fmtMonthToDate(props.modelValue)]
} else {
return []
}
},
set(value) {
let result
if (props.type === 'default' && !props.multi) {
result = utils.dateFormat(value[0], props.format)
} else {
result = value.map(n => utils.dateFormat(n, props.format))
}
emit('update:modelValue', result)
emit('change', result)
validator && validator('change', value)
}
})
const handleClear = () => {
model.value = []
}
const fmtMonthToDate = (str) => {
const _s = str.replace(/-|\/|\./g, ',')
const a = _s.split(',')
a.push('1')
return a.join('/')
}
const setSlideDown = (event) => {
const options = {
event,
pickerHeight: pickerEl.value.offsetHeight,
pickerWidth: props.type === 'range' ? 600 : 300,
dropdownHeight: innerEl.value.offsetHeight || props.downMenuHeight || 310,
fixedWidth: true
}
innerEl.value.set()
dropdownEl.value.visible(options)
}
const setSlideUp = () => {
dropdownEl.value.invisible()
innerEl.value.reset()
}
const handleShowDropdown = (e) => {
if(props.disabled) return false
if (state.slide) {
setSlideUp(e)
} else {
setSlideDown(e)
}
}
const handleChange = (value) => {
model.value = value
setSlideUp()
}
return () => (
<div class="mc-month" ref={pickerEl}>
<Picker data={model.value}
type={props.type}
format={props.format}
multi={props.multi}
errorHint={fieldError.value}
disabled={props.disabled}
separator={props.separator}
placeholder={props.placeholder}
startPlaceholder={props.startPlaceholder}
endPlaceholder={props.endPlaceholder}
clear={props.clear}
onClickPicker={handleShowDropdown}
onClear={handleClear} />
<Dropdown
ref={dropdownEl}
picker={pickerEl.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>
)
}
}
MonthPicker.install = (app) => {
app.component(MonthPicker.name, MonthPicker)
}
const McDatePicker = MonthPicker
export { McDatePicker, McDatePicker as default }