UNPKG

magiccube-vue3

Version:

vue3-js版组件库

217 lines (195 loc) 7.37 kB
import { ref, reactive, computed } from 'vue' import * as utils from '../../utils/common' import Calendar from './calendar' import YearView from './year-view' import MonthView from './month-view' import Toolbar from './toolbar' /** * 日历控件操作功能封装层 */ const Inner = { props: { data: Array, type: String, multi: Boolean, enableStart: String, enableEnd: String, }, emits: ['change'], setup(props, { emit, expose }) { const state = reactive({ view: 'day', year: '', month: '', // range日历中 右侧日历日期显示 endYear: '', endMonth: '', // 年份选择视图中 年份显示 yearChoiceCenter: '' }) const cacheValue = ref([]) const model = computed({ get() { const v = cacheValue.value?.length ? cacheValue.value : props.data return v.map(n => utils.dateFormat(n, 'YYYY/MM/DD')) }, set(value) { cacheValue.value = value } }) /** * 日历视图初始化 * 在dropdown打开时 进行一次初始化 * 在切换月或年时 再次进行日历视图初始化 */ const set = (date = '') => { const initValue = model.value?.length ? model.value[0] : '' const d = date ? new Date(date) : initValue ? new Date(initValue) : new Date() state.view = 'day' state.year = d.getFullYear() state.month = d.getMonth() + 1 } const reset = () => { cacheValue.value = [] } // range类型 日历视图的列表内容 const rangeToView = computed(() => { const d = new Date(`${state.year}/${state.month}/1`) const month = d.getMonth() + 1 d.setMonth(month) const start = utils.dateFormat(`${state.year}/${state.month}/1`, 'YYYY/MM/DD') const end = utils.dateFormat(d, 'YYYY/MM/DD') state.endYear = d.getFullYear() state.endMonth = d.getMonth() + 1 return [start, end] }) // 单日历 日历列表内容 const singleView = computed(() => { return utils.dateFormat(`${state.year}/${state.month}/1`, 'YYYY/MM/DD') }) /** * toolbar中 切换按钮点击函数 */ const dayViewNode = () => { if (props.type === 'range') { return ( <> <div class="mc-date__range left"> <Toolbar type={props.type} forward="left" year={state.year} month={state.month} endYear={state.endYear} endMonth={state.endMonth} onChange={handleChangeToolbar} /> <Calendar v-model={model.value} type={props.type} enableStart={props.enableStart} enableEnd={props.enableEnd} view-date={rangeToView.value[0]} onChange={handleChangeValue} /> </div> <div class="mc-date__range right"> <Toolbar type={props.type} forward="right" year={state.year} month={state.month} endYear={state.endYear} endMonth={state.endMonth} onChange={handleChangeToolbar} /> <Calendar v-model={model.value} type={props.type} enableStart={props.enableStart} enableEnd={props.enableEnd} view-date={rangeToView.value[1]} onChange={handleChangeValue} /> </div> </> ) } else { return ( <> <Toolbar type={props.type} year={state.year} month={state.month} endYear={state.endYear} endMonth={state.endMonth} onChange={handleChangeToolbar} /> <Calendar v-model={model.value} multi={props.multi} enableStart={props.enableStart} enableEnd={props.enableEnd} view-date={singleView.value} onChange={handleChangeValue} /> { props.multi ? ( <div class="mc-date__footer"> <McButton onClick={handleConfirm}>确定</McButton> </div> ) : '' } </> ) } } // 单日历 多选时 需要点击确定按钮 才会更新选中的结果 const handleConfirm = () => { if (props.multi) { emit('change', model.value) } } const handleChangeYear = (year) => { state.view = 'day' state.year = year } const handleChangeMonth = (month) => { state.view = 'day' state.month = month } const handleChangeToolbar = (data) => { const { type, year, month, view } = data if (type === 'view') { state.view = view } else { state.year = year state.month = month } } // 选择日期函数 const handleChangeValue = (value) => { const _val = sortRangeResult(value) model.value = _val emit('change', _val) } // 对结果进行排序 const sortRangeResult = (value) => { return value.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()) } expose({ set, reset }) return () => ( <div class={[ 'mc-date__panel', { range: props.type === 'range' } ]}> { state.view === 'day' ? dayViewNode() : '' } { state.view === 'year' ? <YearView year={state.year} onChange={handleChangeYear} /> : '' } { state.view === 'month' ? <MonthView month={state.month} onChange={handleChangeMonth} /> : '' } </div> ) } } export { Inner, Inner as default }