month-picker 月份選擇器組件
組件介紹
month-picker
是一個用于選擇年月的自定義組件,基于 uni-app 開發,提供了簡潔的月份選擇功能。
解決彈框底部出現底部頁面區域
safe-area屬性設為true時,即可解決這個問題
效果如圖
功能特點
支持選擇年份和月份 可設置默認選中的年月 自動限制當前年份的可選月份 提供清晰的視覺反饋和交互體驗
使用方法
基本用法
<template><month-picker v-model="selectedMonth" @change="handleMonthChange"/>
</template><script>
import MonthPicker from '@/pages/components/date-picker/month-picker.vue'
export default {components: {MonthPicker},data() {return {selectedMonth: '2023-05'}},methods: {handleMonthChange(value) {console.log('選擇的月份:', value)}}
}
</script>
屬性說明屬性名 類型 默認值 說明 value / v-model String “” 綁定值,格式為"YYYY-MM" placeholder String “請選擇月份” 未選擇時的占位文本 safe-area Boolean false 是否開啟底部安全區適配。設為 false 時不會為底部安全區添加額外padding,適合自定義內容已考慮安全區的情況
事件說明事件名 說明 回調參數 input 選擇月份時觸發 (value: String) 格式為"YYYY-MM" change 確認選擇月份時觸發 (value: String) 格式為"YYYY-MM"
month-pick 核心代碼
<template><view><view class="date-selector" @click="showPopup"><text>{{ displayText }}</text><uni-icons type="bottom" size="14" /></view><uni-popup ref="popup" type="bottom" class="custom-picker-popup" :safe-area="false" :background-lock="true"><view class="custom-picker"><view class="picker-header"><text @click="closePopup">取消</text><text @click="confirmMonth">確定</text></view><picker-view :value="dateValue" indicator-class='pickerCol' @change="handlePickerChange"><picker-view-column class="picker-item"><view v-for="(year, i) in yearList" :key="i">{{ year }}年</view></picker-view-column><picker-view-column class="picker-item"><view v-for="(month, i) in maxMonth" :key="i">{{ month }}月</view></picker-view-column></picker-view></view></uni-popup></view>
</template><script>
export default {props: {// 默認選中的年月(格式:YYYY-MM)value: {type: String,default: "",},// 占位文本placeholder: {type: String,default: "請選擇月份",},},data() {return {yearList: [],selectedYear: new Date().getFullYear(),selectedMonth: new Date().getMonth() + 1,dateValue: [0,0],maxMonth: 12,};},computed: {displayText() {const currentTime = `${new Date().getFullYear()}年${new Date().getMonth() + 1}月`;if (!this.selectedYear || !this.selectedMonth) return currentTime;return `${this.selectedYear}年${this.selectedMonth}月`;},},created() {this.generateYearList();this.setDefaultValue();},mounted() {},methods: {generateYearList() {const currentYear = new Date().getFullYear();this.yearList = Array.from({ length: 10 },(_, i) => currentYear - 9 + i);},setDefaultValue() {const [year, month] = this.value.split("-");if (!year || !month) {if(this.selectedYear){this.dateValue[0] = this.yearList.indexOf(parseInt(this.selectedYear));this.dateValue[1] = parseInt(this.selectedMonth) - 1;this.updateMaxMonth(parseInt(this.selectedYear));}return;};this.dateValue[0] = this.yearList.indexOf(parseInt(year));this.dateValue[1] = parseInt(month ) - 1;this.updateMaxMonth(parseInt(year));},updateMaxMonth(year) {if (year === new Date().getFullYear()) {this.maxMonth = new Date().getMonth() + 1;} else {this.maxMonth = 12;}},showPopup() {this.$refs.popup.open();},closePopup() {this.$refs.popup.close();},confirmMonth() {this.selectedYear = this.yearList[this.dateValue[0]];this.selectedMonth = this.dateValue[1] + 1;this.$emit("input",`${this.selectedYear}-${this.selectedMonth.toString().padStart(2, "0")}`);this.$emit("change",`${this.selectedYear}-${this.selectedMonth.toString().padStart(2, "0")}`);this.closePopup();},handlePickerChange(e) {const [yearIndex, monthIndex] = e.detail.value;this.updateMaxMonth(this.yearList[yearIndex])this.dateValue[0] = yearIndex;this.dateValue[1] = Math.min(monthIndex,this.maxMonth - 1) ;},},
};
</script><style scoped lang="scss">
.picker-view {display: flex;align-items: center;padding: 10px;background-color: #f5f5f5;border-radius: 4px;
}
.custom-picker {background-color: #fff;border-radius: 12px 12px 0px 0px;
}
.date-selector {font-size: 32rpx;color: #020b1c;
}
.picker-header {display: flex;justify-content: space-between;padding: 12px 16px;border-bottom: 1px solid #eee;
}
picker-view {height: 560rpx;
}
::v-deep .pickerCol {height: 90rpx;line-height: 90rpx;border-radius: 20rpx;
}.picker-item {font-size: 32rpx;color: #333;text-align: center;view {line-height: 90rpx;}
}
::v-deep .uni-picker-view-highlight {/* 修改選中項的高亮背景 */background-color: #eee !important;height: 80rpx;
}
</style>
注意事項
當選擇的年份為當前年份時,月份選項會自動限制為當前月份及之前的月份 年份范圍為當前年份前9年至當前年份 組件使用了 uni-popup 和 uni-icons,請確保項目中已引入這些組件 safe-area
屬性設為false
時,彈出層不會為底部安全區添加額外padding,適合自定義內容已考慮安全區的情況;設為true
時會自動適配底部安全區域,避免內容被遮擋