calendar,vue+nui app 日历,nui app有月份日历,Calendar 日历优化出月份选择

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,优化使用

原文地址:https://www.cnblogs.com/FACESCORE/p/13214870.html