DateRangePicker 日期范围选择器
DateRangePicker 日期范围选择器,基于 el-date-picker 封装,默认按月选择,自动补齐首尾日期。
快速使用
<DateRangePicker v-model="dateRange"/><DateRangePicker v-model="dateRange"type="daterange"/><DateRangePicker v-model="dateRange"type="yearrange"/>Props
modelValue Array v-model 绑定值,格式['YYYY-MM-DD','YYYY-MM-DD']typeString 选择类型:'monthrange'(默认)|'daterange'|'yearrange'valueFormat String 输出日期格式,默认'YYYY-MM-DD'clearable 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 等原生属性)<template><el-date-picker v-model="innerValue":type="type":value-format="innerValueFormat":clearable="clearable"range-separator="-":start-placeholder="startPlaceholder":end-placeholder="endPlaceholder"v-bind="$attrs"/></template><script setup>import{computed, onMounted}from'vue';defineOptions({name:'DateRangePicker'});const props=defineProps({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 emit=defineEmits(['update:modelValue']);const now=new Date();const currentYear=now.getFullYear();// 默认值:本年度1月1日 ~12月31日 const defaultRange=computed(()=>{ if(props.type==='yearrange')return [`${currentYear}`,`${currentYear}`];return [`${currentYear}-01-01`,`${currentYear}-12-31`];});onMounted(()=>{ if(props.autoDefault&&(!props.modelValue||props.modelValue.length<2)){emit('update:modelValue',[...defaultRange.value]);}});// 内部传给 el-date-picker 的formatconst innerValueFormat=computed(()=>{ if(props.type==='monthrange')return 'YYYY-MM';if(props.type==='yearrange')return 'YYYY';return props.valueFormat;});//获取某月的最后一天 const lastDayOfMonth=(year,month)=>new Date(year,month,0).getDate();const innerValue=computed({ get(){ if(!props.modelValue||props.modelValue.length<2){ if(!props.autoDefault)return null;//默认本年度 if(props.type==='monthrange')return [`${currentYear}-01`,`${currentYear}-12`];if(props.type==='yearrange')return [`${currentYear}`,`${currentYear}`];return [`${currentYear}-01-01`,`${currentYear}-12-31`];} if(props.type==='monthrange'){//YYYY-MM-DD → YYYY-MM return props.modelValue.map(v=>(v||'').substring(0,7));}if(props.type==='yearrange'){// YYYY-MM-DD → YYYYreturnprops.modelValue.map(v=>(v||'').substring(0,4));}returnprops.modelValue;}, set(val){if(!val||val.length<2){emit('update:modelValue',[]);return;}if(props.type==='monthrange'){// 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.type==='yearrange'){// 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>