Heim > Web-Frontend > View.js > Hauptteil

So implementieren Sie eine Kalenderkomponente mit Vue3

WBOY
Freigeben: 2023-05-10 08:55:07
nach vorne
1582 Leute haben es durchsucht

以下是一个基于 Vue 3 实现的简单日历组件的代码示例。这个日历组件包含了前一个月、当前月、下一个月的日期,并且可以支持选择日期、切换月份等功能。

<template>
  <div class="calendar">
    <div class="header">
      <button class="prev" @click="prevMonth">&lt;</button>
      <div class="title">{{ title }}</div>
      <button class="next" @click="nextMonth">&gt;</button>
    </div>
    <div class="weekdays">
      <div v-for="day in daysOfWeek" :key="day" class="day">{{ day }}</div>
    </div>
    <div class="days">
      <div
        v-for="day in days"
        :key="day.date"
        :class="{
          today: isToday(day),
          selected: isSelected(day),
          notCurrentMonth: isNotCurrentMonth(day),
        }"
        @click="select(day)"
      >
        {{ day.day }}
      </div>
    </div>
  </div>
</template>

<script>
  import { ref, computed } from "vue";

  export default {
    name: "FeiCalendar",
    props: {
      selectedDate: Date,
    },
    emits: ["update:selectedDate"],
    setup(props, { emit }) {
      const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
      const currentDate = ref(new Date());
      const selectedDate = ref(props.selectedDate || currentDate.value);

      const daysOfWeek = computed(() => {
        return weekdays;
      });

      const days = computed(() => {
        const year = currentDate.value.getFullYear();
        const month = currentDate.value.getMonth();
        const daysInMonth = new Date(year, month + 1, 0).getDate();
        const daysInLastMonth = new Date(year, month, 0).getDate();
        const firstDayOfMonth = new Date(year, month, 1).getDay();

        const days = [];
        let day = 1;
        let lastMonthDay = daysInLastMonth - firstDayOfMonth + 1;
        let nextMonthDay = 1;

        for (let i = 0; i < 6 * 7; i++) {
          if (i < firstDayOfMonth) {
            days.push({
              date: new Date(year, month - 1, lastMonthDay),
              day: lastMonthDay,
              isLastMonth: true,
              isNextMonth: false,
            });
            lastMonthDay++;
          } else if (i >= firstDayOfMonth + daysInMonth) {
            days.push({
              date: new Date(year, month + 1, nextMonthDay),
              day: nextMonthDay,
              isLastMonth: false,
              isNextMonth: true,
            });
            nextMonthDay++;
          } else {
            const date = new Date(year, month, day);
            days.push({ date, day, isLastMonth: false, isNextMonth: false });
            day++;
          }
        }

        return days;
      });

      const title = computed(
        () =>
          `${currentDate.value.toLocaleString("default", {
            month: "long",
          })} ${currentDate.value.getFullYear()}`
      );

      const prevMonth = () => {
        currentDate.value = new Date(
          currentDate.value.getFullYear(),
          currentDate.value.getMonth() - 1,
          1
        );
      };

      const nextMonth = () => {
        currentDate.value = new Date(
          currentDate.value.getFullYear(),
          currentDate.value.getMonth() + 1,
          1
        );
      };

      const isToday = (day) => {
        const today = new Date();
        return day.date.toDateString() === today.toDateString();
      };

      const isSelected = (day) => {
        return day.date.toDateString() === selectedDate.value.toDateString();
      };

      const isNotCurrentMonth = (day) => {
        return day.isLastMonth || day.isNextMonth;
      };

      const select = (day) => {
        selectedDate.value = day.date;
        emit("update:selectedDate", day.date);
      };

      return {
        daysOfWeek,
        days,
        title,
        prevMonth,
        nextMonth,
        isToday,
        isSelected,
        isNotCurrentMonth,
        select,
      };
    },
  };
</script>

<style>
  .calendar {
    max-width: 500px;
    margin: 0 auto;
    font-family: Arial, sans-serif;
  }

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
  }

  .title {
    font-size: 18px;
    font-weight: bold;
  }

  .weekdays {
    display: flex;
    justify-content: space-around;
    margin-bottom: 10px;
  }

  .day {
    width: 30px;
    height: 30px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 50%;
  }

  .days {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    grid-gap: 10px;
  }

  .today {
    background-color: lightblue;
  }

  .selected {
    background-color: blue;
    color: white;
  }

  .notCurrentMonth {
    color: #ccc;
  }
</style>
Nach dem Login kopieren

使用该组件时,可以将selectedDate属性绑定到一个父组件中的数据,这个数据将会存储选中的日期。例如:

<template>
  <div>
    <!-- 用法一 -->
    <FeiCalendar
      :selectedDate="selectedDate"
      @update:selectedDate="onSelectedDateUpdated"
    />
    <!-- 用法二 -->
    <!-- <FeiCalendar v-model:selectedDate="selectedDate" /> -->
    <p>Selected date: {{ selectedDate }}</p>
  </div>
</template>

<script>
  import FeiCalendar from "./FeiCalendar.vue";

  export default {
    components: {
      FeiCalendar,
    },
    data() {
      return {
        selectedDate: new Date(),
      };
    },
    watch: {
      selectedDate(nv) {
        console.log("nv", nv);
      },
    },
    methods: {
      onSelectedDateUpdated(selectedDate) {
        this.selectedDate = selectedDate;
      },
    },
  };
</script>
Nach dem Login kopieren

这是一个简单的示例,可以根据自己的需求对代码进行修改和扩展。

Das obige ist der detaillierte Inhalt vonSo implementieren Sie eine Kalenderkomponente mit Vue3. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage