uni-app 日历组件的实现

uni-app 日历组件的实现

以下是一个基于 uni-app 的简单日历组件实现代码,包括了日历的基本布局和日期选择功能:

<template>
  <view class="calendar">
    <view class="calendar-header">
      <view class="calendar-prev" @click="prevMonth">上个月</view>
      <view class="calendar-title">{{ year }}年{{ month }}月</view>
      <view class="calendar-next" @click="nextMonth">下个月</view>
    </view>
    <view class="calendar-body">
      <view class="calendar-weekdays">
        <view
          class="calendar-weekday"
          v-for="(weekday, index) in weekdays"
          :key="index"
        >
          {{ weekday }}
        </view>
      </view>
      <view class="calendar-dates">
        <view
          class="calendar-date"
          v-for="(date, index) in dates"
          :key="index"
          :class="{ 'calendar-date-today': isToday(date), 'calendar-date-selected': isSelected(date) }"
          @click="selectDate(date)"
        >
          {{ date || '' }}
        </view>
      </view>
    </view>
  </view>
</template>

<script>
  export default {
    name: "calendar",
    data() {
      return {
        year: new Date().getFullYear(),
        month: new Date().getMonth() + 1,
        weekdays: ["日", "一", "二", "三", "四", "五", "六"],
        selectedDate: null,
      };
    },
    computed: {
      dates() {
        const firstDayOfMonth = new Date(this.year, this.month - 1, 1);
        const lastDayOfMonth = new Date(this.year, this.month, 0);
        const dates = [];
        for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
          dates.push(i);
        }
        for (let i = 1; i < firstDayOfMonth.getDay(); i++) {
          dates.unshift(null);
        }
        return dates;
      },
    },
    methods: {
      prevMonth() {
        if (this.month === 1) {
          this.year -= 1;
          this.month = 12;
        } else {
          this.month -= 1;
        }
      },
      nextMonth() {
        if (this.month === 12) {
          this.year += 1;
          this.month = 1;
        } else {
          this.month += 1;
        }
      },
      isToday(date) {
        const today = new Date();
        return (
          this.year === today.getFullYear() &&
          this.month === today.getMonth() + 1 &&
          date === today.getDate()
        );
      },
      isSelected(date) {
        return this.selectedDate && this.selectedDate === date;
      },
      selectDate(date) {
        this.selectedDate = date;
        this.$emit("select", new Date(this.year, this.month - 1, date));
      },
    },
  };
</script>

<style scoped>
  .calendar {
    width: 280px;
    border: 1px solid #ccc;
    border-radius: 4px;
    font-size: 14px;
    background: #fff;
  }

  .calendar-header {
    display: flex;
    justify-content: space-between;
    padding: 8px;
    font-weight: 600;
  }

  .calendar-title {
    text-align: center;
    flex: 1;
  }

  .calendar-prev,
  .calendar-next {
    cursor: pointer;
  }

  .calendar-body {
    display: flex;
    flex-direction: column;
  }

  .calendar-weekdays {
    display: flex;
  }

  .calendar-weekday {
    flex: 1;
    padding: 8px;
    text-align: center;
    border-bottom: 1px solid #ccc;
    font-weight: 600;
  }

  .calendar-dates {
    display: flex;
    flex-wrap: wrap;
  }

  .calendar-date {
    width: calc(100% / 7);
    padding: 8px;
    text-align: center;
    border-bottom: 1px solid #ccc;
    cursor: pointer;
  }

  .calendar-date-today {
    color: blue;
    font-weight: 600;
  }

  .calendar-date-selected {
    background-color: rgb(60, 156, 255);
    color: rgb(255, 255, 255);
  }
</style>

使用方法:

<template>
  <view>
    <calendar @select="handleDateSelect" />
  </view>
</template>

<script>
  // 在根目录下的 components 文件夹添加的组件无需导入

  export default {
    methods: {
      handleDateSelect(date) {
        console.log(date);
      },
    },
  };
</script>

该组件实现了基本的日历布局和日期选择功能,并用 props 和 emit 方法实现了父子组件之间的数据传递。根据需要,可以对该组件进行进一步的定制和扩展。

posted @ 2023-04-07 15:12  飞仔FeiZai  阅读(420)  评论(0编辑  收藏  举报