DateRangePicker 日期范围选择器
发布时间:2026/7/1 14:00:00
分类:文化教育
浏览:1234

DateRangePicker 日期范围选择器基于 el-date-picker 封装默认按月选择自动补齐首尾日期。快速使用DateRangePicker v-modeldateRange/DateRangePicker v-modeldateRangetypedaterange/DateRangePicker v-modeldateRangetypeyearrange/PropsmodelValue Array v-model 绑定值格式[YYYY-MM-DD,YYYY-MM-DD]typeString 选择类型monthrange(默认)|daterange|yearrangevalueFormat String 输出日期格式默认YYYY-MM-DDclearable Boolean 是否可清空默认falseautoDefault Boolean 无值时自动填入本年度默认 true设为false则不填 startPlaceholder String 开始日期占位默认开始日期endPlaceholder String 结束日期占位默认结束日期默认行为- 默认选中本年度1月1日 ~12月31日 - 月模式选中1月→3月自动返回[2026-01-01,2026-03-31]- 年模式选中2024→2025自动返回[2024-01-01,2025-12-31]- 不可清空可传入 clearable 开启 - 支持$attrs透传disabledDate、size 等原生属性templateel-date-picker v-modelinnerValue:typetype:value-formatinnerValueFormat:clearableclearablerange-separator-:start-placeholderstartPlaceholder:end-placeholderendPlaceholderv-bind$attrs//templatescript setupimport{computed, onMounted}fromvue;defineOptions({name:DateRangePicker});const propsdefineProps({modelValue:{type: Array, default:()[]}, // 类型monthrange(默认按月)|daterange(按日)|yearrange(按年)type:{type: String, default:monthrange}, valueFormat:{type: String, default:YYYY-MM-DD}, clearable:{type: Boolean, default:false}, autoDefault:{type: Boolean, default:true}, // 是否自动填入本年度默认值 startPlaceholder:{type: String, default:开始日期}, endPlaceholder:{type: String, default:结束日期},});const emitdefineEmits([update:modelValue]);const nownew Date();const currentYearnow.getFullYear();// 默认值本年度1月1日 ~12月31日 const defaultRangecomputed((){ if(props.typeyearrange)return [${currentYear},${currentYear}];return [${currentYear}-01-01,${currentYear}-12-31];});onMounted((){ if(props.autoDefault(!props.modelValue||props.modelValue.length2)){emit(update:modelValue,[...defaultRange.value]);}});// 内部传给 el-date-picker 的formatconst innerValueFormatcomputed((){ if(props.typemonthrange)return YYYY-MM;if(props.typeyearrange)return YYYY;return props.valueFormat;});//获取某月的最后一天 const lastDayOfMonth(year,month)new Date(year,month,0).getDate();const innerValuecomputed({ get(){ if(!props.modelValue||props.modelValue.length2){ if(!props.autoDefault)return null;//默认本年度 if(props.typemonthrange)return [${currentYear}-01,${currentYear}-12];if(props.typeyearrange)return [${currentYear},${currentYear}];return [${currentYear}-01-01,${currentYear}-12-31];} if(props.typemonthrange){//YYYY-MM-DD → YYYY-MM return props.modelValue.map(v(v||).substring(0,7));}if(props.typeyearrange){// YYYY-MM-DD → YYYYreturnprops.modelValue.map(v(v||).substring(0,4));}returnprops.modelValue;}, set(val){if(!val||val.length2){emit(update:modelValue,[]);return;}if(props.typemonthrange){// val[2024-01,2024-03]→[2024-01-01,2024-03-31]const[endYear, endMonth]val[1].split(-).map(Number);const start${val[0]}-01;const end${val[1]}-${String(lastDayOfMonth(endYear, endMonth)).padStart(2,0)};emit(update:modelValue,[start, end]);}elseif(props.typeyearrange){// val[2024,2025]→[2024-01-01,2025-12-31]emit(update:modelValue,[${val[0]}-01-01,${val[1]}-12-31]);}else{emit(update:modelValue, val);}}});/script