UNPKG

magiccube-vue3

Version:

vue3-js版组件库

217 lines (194 loc) 7.11 kB
import { ref, reactive, computed } from 'vue' import * as utils from '../../utils/common' import MonthCell from './month-cell' import YearCell from './year-cell' /** * 日历控件操作功能封装层 */ const Inner = { props: { data: Array, /** 支持两种类型 default和range,其中default包含单选和多选 */ type: { type: String, default: 'default' }, multi: Boolean, enableStart: String, enableEnd: String, }, emits: ['change'], setup(props, { emit, expose }) { const state = reactive({ view: 'month', year: '', // range日历中 右侧日历日期显示 endYear: '', }) 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 = cacheValue.value?.length? cacheValue.value[0] : '' const d = date ? new Date(date) : initValue ? new Date(initValue) : new Date() state.view = 'month' state.year = d.getFullYear() if(props.type === 'range') { state.endYear = state.year + 1 } } const reset = () => { cacheValue.value = [] } /** * toolbar中 切换按钮点击函数 */ const handleChangeView = (e, action) => { e.stopPropagation() switch (action) { // 上年 case 'prev_year': { set(`${state.year - 1}/1/1`) break } // 下年 case 'next_year': { set(`${state.year + 1}/1/1`) break } case 'change_year': { state.view = 'year' break } } } // 年份或月份切换选择函数 const handleChangeYear = (value) => { state.view = 'month' state.year = value } const handleSelectMonth = (value) => { const v = sortRangeResult(value) model.value = v emit('change', v) } const toolbarNode = (forward) => ( <div class="mc-month__toolbar"> <div class="mc-month__toolbar--child"> { props.type !== 'range' || (props.type === 'range' && forward === 'left') ? ( <> <span class="mc-month__toolbar--year" onClick={(e) => handleChangeView(e, 'prev_year')}></span> </> ) : '' } </div> <div class="mc-month__toolbar--child current-date-view"> <span class={{ disabled: props.type === 'range' }} onClick={(e) => handleChangeView(e, 'change_year')}> {forward === 'right'? state.endYear : state.year}年 </span> </div> <div class="mc-month__toolbar--child"> { props.type !== 'range' || (props.type === 'range' && forward === 'right') ? ( <> <span class="mc-month__toolbar--year right" onClick={(e) => handleChangeView(e, 'next_year')}></span> </> ) : '' } </div> </div> ) const monthViewNode = () => { if (props.type === 'range') { return ( <> <div class="mc-month__range left"> {toolbarNode('left')} <MonthCell v-model={model.value} year={state.year} type={props.type} enableStart={props.enableStart} enableEnd={props.enableEnd} onChange={handleSelectMonth} /> </div> <div class="mc-month__range right"> {toolbarNode('right')} <MonthCell v-model={model.value} year={state.endYear} type={props.type} enableStart={props.enableStart} enableEnd={props.enableEnd} onChange={handleSelectMonth} /> </div> </> ) } else { return ( <> {toolbarNode()} <MonthCell v-model={model.value} year={state.year} type={props.type} multi={props.multi} enableStart={props.enableStart} enableEnd={props.enableEnd} onChange={handleSelectMonth} /> { props.multi ? ( <div class="mc-month__footer"> <McButton onClick={handleConfirm}>确定</McButton> </div> ) : '' } </> ) } } // 单日历 多选时 需要点击确定按钮 才会更新选中的结果 const handleConfirm = () => { if (props.multi) { emit('change', model.value) } } // 对结果进行排序 const sortRangeResult = (value) => { return value.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()) } expose({ set, reset }) return () => ( <div class={[ 'mc-month__panel', { range: props.type === 'range' } ]}> { state.view === 'year' ? <YearCell year={state.year} onChange={handleChangeYear} /> : '' } { state.view === 'month' ? monthViewNode() : '' } </div> ) } } export { Inner, Inner as default }