nui app有月份选择日历
<uni-calendar ref="calendar" :date="date" :topTabCur="topTabCur" :insert="false" :lunar="false" :disable-before="true" :showMonth="false" :start-date="startDate" :end-date="endDate" :clearDate="false" @confirm="confirmCalendar" />
打开日历
toggleCalendar() { // this.showUniCalendar = !this.showUniCalendar const showStatus = this.$refs.calendar.show showStatus ? this.$refs.calendar.close() : this.$refs.calendar.open() if (!showStatus && this.selectedDate) { this.date = ‘‘ this.date = this.topTabCur === 0 ? this.lastChoiceDate : this.lastChoiceMonth } },
//获取回调的日期数据 confirmCalendar(selected) { const { fulldate, clearFlag } = selected switch (this.topTabCur) { case 0: this.lastChoiceDate = clearFlag ? ‘‘ : fulldate this.date = this.lastChoiceDate this.selectedDate = clearFlag ? ‘‘ : `${fulldate.replace(/-/g, ‘‘)}` break case 1: this.lastChoiceMonth = clearFlag ? ‘‘ : fulldate this.date = this.lastChoiceMonth this.selectedMonth = clearFlag ? ‘‘ : `${fulldate.replace(/-/g, ‘‘).substring(0, 6)}` break default: } },
//切换日和月查询 tabClick(i) { this.topTabCur = i this.$set(this, ‘topTabCur‘, i) this.$refs.calendar.changeTopTabCur(i) // this.date = ‘‘ this.date = this.topTabCur === 0 ? this.lastChoiceDate : this.lastChoiceMonth // this.$emit("changeTopTabCur"); },
<template> <view class="uni-calendar"> <view v-if="!insert&&show" class="uni-calendar__mask" :class="{‘uni-calendar--mask-show‘:aniMaskShow}" @click="clean" ></view> <view v-if="insert || show" class="uni-calendar__content" :class="{‘uni-calendar--fixed‘:!insert,‘uni-calendar--ani-show‘:aniMaskShow}" > <view class="uni-calendar__header"> <view class="uni-calendar__header-btn-box" @click.stop="preYear"> <view class="uni-calendar__header-btn uni-calendar--left"></view> <view class="uni-calendar__header-btn min uni-calendar--left"></view> </view> <view v-if="!showMonthBoxs" class="uni-calendar__header-btn-box" @click.stop="pre"> <view class="uni-calendar__header-btn uni-calendar--left"></view> </view> <text class="uni-calendar__header-text" @click="showMonthBox" v-if="!showMonthBoxs" >{{ (nowDate.year||‘‘) +‘年‘+( nowDate.month||‘‘) +‘月‘}}</text> <text class="uni-calendar__header-text" @click="showMonthBox" v-if="showMonthBoxs" >{{ (nowDate.year||‘‘) +‘年‘}}</text> <!-- </picker> --> <view v-if="!showMonthBoxs" class="uni-calendar__header-btn-box" @click.stop="next"> <view class="uni-calendar__header-btn uni-calendar--right"></view> </view> <view class="uni-calendar__header-btn-box" @click.stop="nextYear"> <view class="uni-calendar__header-btn min uni-calendar--right"></view> <view class="uni-calendar__header-btn uni-calendar--right"></view> </view> <!-- <text class="uni-calendar__backtoday" @click="backtoday">回到今天</text> --> </view> <view v-if="!showMonthBoxs" class="uni-calendar__box"> <view v-if="showMonth" class="uni-calendar__box-bg"> <text class="uni-calendar__box-bg-text">{{nowDate.month}}</text> </view> <view class="uni-calendar__weeks"> <view class="uni-calendar__weeks-day"> <text class="uni-calendar__weeks-day-text">日</text> </view> <view class="uni-calendar__weeks-day"> <text class="uni-calendar__weeks-day-text">一</text> </view> <view class="uni-calendar__weeks-day"> <text class="uni-calendar__weeks-day-text">二</text> </view> <view class="uni-calendar__weeks-day"> <text class="uni-calendar__weeks-day-text">三</text> </view> <view class="uni-calendar__weeks-day"> <text class="uni-calendar__weeks-day-text">四</text> </view> <view class="uni-calendar__weeks-day"> <text class="uni-calendar__weeks-day-text">五</text> </view> <view class="uni-calendar__weeks-day"> <text class="uni-calendar__weeks-day-text">六</text> </view> </view> <view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex"> <!-- <view v-if="weekIndex<30"> --> <view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex" > <calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" :date="date" @change="choiceDate" ></calendar-item> </view> <!-- </view> --> </view> </view> <view v-else class="uni-calendar__box text-center fs18 fc6 padding-tb-sm"> <view class="calendar__month"> <view class="calendar-item__wrapper" v-for="(month,monthIndex) in 12" :key="monthIndex"> <view class="calendar-item" :class="{ ‘isDay-text‘: nowDate.month == month && nowDate.year == calendar.year , ‘checked‘: nowDate.month == month && nowDate.year == calendar.year && date, ‘disable‘: disabledMonth(month) }" @click="changeMonth(month)" >{{month}}月</view> </view> </view> </view> <view class="clear-btn" @click="clear"> 清空 </view> </view> </view> </template> <script> import Calendar from "./util.js"; import calendarItem from "./uni-calendar-item.vue"; /** * Calendar 日历 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等 * @tutorial https://ext.dcloud.net.cn/plugin?id=56 * @property {String} date 自定义当前时间,默认为今天 * @property {Boolean} lunar 显示农历 * @property {String} startDate 日期选择范围-开始日期 * @property {String} endDate 日期选择范围-结束日期 * @property {Boolean} range 范围选择 * @property {Boolean} insert = [true|false] 插入模式,默认为false * @value true 弹窗模式 * @value false 插入模式 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容 * @property {Array} selected 打点,期待格式[{date: ‘2019-06-27‘, info: ‘签到‘, data: { custom: ‘自定义信息‘, name: ‘自定义消息头‘,xxx:xxx... }}] * @property {Boolean} showMonth 是否选择月份为背景 * @event {Function} change 日期改变,`insert :ture` 时生效 * @event {Function} confirm 确认选择`insert :false` 时生效 * @event {Function} monthSwitch 切换月份时触发 * @example <uni-calendar :insert="true":lunar="true" :start-date="‘2019-3-2‘":end-date="‘2019-5-20‘"@change="change" /> */ export default { components: { calendarItem }, props: { date: { type: String, default: "" }, selected: { type: Array, default() { return []; } }, topTabCur: { type: Number, default: 0 }, lunar: { type: Boolean, default: false }, startDate: { type: String, default: "" }, endDate: { type: String, default: "" }, range: { type: Boolean, default: false }, insert: { type: Boolean, default: true }, showMonth: { type: Boolean, default: true }, clearDate: { type: Boolean, default: true } }, data() { return { show: false, weeks: [], calendar: {}, nowDate: "", aniMaskShow: false, showMonthBoxs: false, }; }, watch: { date(newVal) { this.cale.setDate(newVal); this.init(this.cale.selectDate.fullDate); }, startDate(val) { this.cale.resetSatrtDate(val); }, endDate(val) { this.cale.resetEndDate(val); }, selected(newVal) { this.cale.setSelectInfo(this.nowDate.fullDate, newVal); this.weeks = this.cale.weeks; // this.weeks.splice(0,4); } }, created() { // 获取日历方法实例 this.cale = new Calendar({ // date: new Date(), selected: this.selected, startDate: this.startDate, endDate: this.endDate, range: this.range }); // 选中某一天 this.cale.setDate(this.date); this.init(this.cale.selectDate.fullDate); // this.setDay }, methods: { // 取消穿透 clean() { if (!this.insert) { this.close() } }, bindDateChange(e) { const value = e.detail.value + "-1"; this.cale.setDate(value); this.init(value); }, /** * 初始化日期显示 * @param {Object} date */ init(date) { this.nowDate = this.calendar = this.cale.getInfo(date); if (this.topTabCur == 1) { this.showMonthBox(); } else { this.weeks = this.cale.weeks; } }, /** * 打开日历弹窗 */ open() { // 弹窗模式并且清理数据 if (this.clearDate && !this.insert) { this.cale.cleanMultipleStatus(); this.cale.setDate(this.date); this.init(this.cale.selectDate.fullDate); } this.show = true; this.$nextTick(() => { setTimeout(() => { this.aniMaskShow = true; }, 50); }); }, /** * 关闭日历弹窗 */ close() { this.aniMaskShow = false; this.$nextTick(() => { setTimeout(() => { this.show = false; this.$emit("close"); }, 300); }); }, /** * 确认按钮 */ confirm() { this.setEmit("confirm"); this.close(); }, changeTopTabCur(t) { if (t == 1) { this.showMonthBoxs = true; } else { this.showMonthBoxs = false; this.weeks = this.cale.weeks; } }, /** * 变化触发 */ change() { if (!this.insert) return; this.setEmit("change"); }, /** * 选择月份触发 */ monthSwitch() { let { year, month } = this.nowDate; this.$emit("monthSwitch", { year, month: Number(month) }); }, /** * 派发事件 * @param {Object} name */ setEmit(name) { let { year, month, date, fullDate, lunar, extraInfo, clearFlag=false } = this.calendar; this.$emit(name, { clearFlag, topTabCur: this.topTabCur, range: this.cale.multipleStatus, year, month, date, fulldate: fullDate, lunar, extraInfo: extraInfo || {} }); }, /** * 选择天触发 * @param {Object} weeks */ choiceDate(weeks) { if (weeks.disable) return; this.calendar = weeks; // 设置多选 this.cale.setMultiple(this.calendar.fullDate); this.weeks = this.cale.weeks; this.setEmit("confirm"); this.close(); this.change(); }, /** * 回到今天 */ backtoday() { let date = this.cale.getDate(new Date()).fullDate; this.cale.setDate(date); this.init(date); this.change(); }, /** * 上个月 */ pre() { const preDate = this.cale.getDate(this.nowDate.fullDate, -1, "month") .fullDate; this.setDate(preDate); this.monthSwitch(); }, /** * 下个月 */ next() { const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, "month") .fullDate; this.setDate(nextDate); this.monthSwitch(); }, /** * 上一年 */ preYear() { const preDate = this.cale.getDate(this.nowDate.fullDate, -1, "year") .fullDate; this.setDate(preDate); this.monthSwitch(); }, /** * 下一年 */ nextYear() { const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, "year") .fullDate; this.setDate(nextDate); this.monthSwitch(); }, /** * 设置日期 * @param {Object} date */ setDate(date) { this.cale.setDate(date); this.weeks = this.cale.weeks; // this.weeks.splice(0,4); this.nowDate = this.cale.getInfo(date); }, showMonthBox() { this.showMonthBoxs = true; }, disabledMonth(month) { const endYear = new Date(this.endDate).getFullYear() const endMonth = new Date(this.endDate).getMonth()+1 return this.nowDate.year > endYear || (this.nowDate.year === endYear && month >= endMonth) }, changeMonth(m) { if (this.disabledMonth(m)) return let { year, month } = this.nowDate; let n = m - month; const nextDate = this.cale.getDate(this.nowDate.fullDate, n, "month") .fullDate; const newDate = `${nextDate.substring(0, 8)}01` this.setDate(newDate); this.monthSwitch(); if (this.topTabCur == 1) { this.calendar = this.cale.getInfo(newDate); // 设置多选 this.cale.setMultiple(this.calendar.fullDate); this.weeks = this.cale.weeks; this.setEmit("confirm"); this.close(); this.change(); } else { this.showMonthBoxs = false; } }, clear() { // const year = new Date().getFullYear() // const month = new Date().getMonth() + 1 // const date = new Date().getDate() // const today = `${year}-${month >= 10 ? month : ‘0‘ + month}-${date >= 10 ? date : ‘0‘ + date}` // // debugger // this.setDate(today); // this.calendar = this.cale.getInfo(today); // this.calendar.clearFlag = true // // 设置多选 // this.weeks = this.cale.weeks; // this.setEmit("confirm"); // this.close(); // this.change(); this.backtoday() this.calendar.clearFlag = true this.setEmit("confirm"); this.close(); } } }; </script>
样式做了小优化
备注:Calendar 日历来源于https://ext.dcloud.net.cn/plugin?id=56,优化使用