Задать вопрос
@Esm322

Как отрендерить календарь, чтобы числа дней выводились в соответствии с днями недели?

Необходимо, чтобы числа каждого месяца отображались в соответствии с днями недели.

const date = reactive({
  currentDate: new Date(),
});
const currentYear = ref(date.currentDate.getFullYear());
const currentMonth = ref(date.currentDate.getMonth());
const currentDay = ref(date.currentDate.getDate());

const lastDayMonth = computed(
  () => new Date(currentYear.value, currentMonth.value + 1, 0).getDate(),
);
const firstDayMonth = computed(
  () => new Date(currentYear.value, currentMonth.value, 1).getDate(),
);

const getCalendar = computed(() => {
  const currMonthDays = [];
  const preMonthDays = [];

  for (let i = 1; i <= lastDayMonth.value; i += 1) {
    currMonthDays.push(i);
  }

  for (let i = firstDayMonth.value; i > 0; i -= 1) {
    preMonthDays.push('');
  }

  const resDays = [...preMonthDays, ...currMonthDays];

  return resDays;
});

Есть проблема именно с этим циклом:

for (let i = firstDayMonth.value; i > 0; i -= 1) {
    preMonthDays.push('');
  }

Но в чём именно ошибка, не могу понять.
  • Вопрос задан
  • 179 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Отдельные циклы для чисел за текущий и предыдущий месяцы (кстати, а где у вас следующий?) не нужны. Чтобы получить число, надо не на счётчик цикла смотреть, а на дату - начальным значением будет первое число месяца минус количество дней, прошедших с последнего понедельника предыдущего месяца. Цикл крутить надо не до конца месяца, а немного дальше - чтобы общее количество чисел было кратно семи (т.е., чтобы в последней неделе не было отсутствующих дней) и всегда одно и то же (чтобы размер календаря не зависел от отображаемого месяца). Вот так:

const month = computed(() => {
  const today = new Date().setHours(0, 0, 0, 0);
  const m = date.value.getMonth();
  const d = new Date(date.value.getFullYear(), m, 0);
  d.setDate(d.getDate() - (d.getDay() || 7));

  return Array.from({ length: 42 }, () => (
    d.setDate(d.getDate() + 1),
    {
      date: d.getDate(),
      currMonth: d.getMonth() === m,
      today: +d === today,
    }
  ));
});

<div class="calendar">
  <div
    v-for="n in weekdays"
    v-text="n"
    class="weekday"
  ></div>
  <div
    v-for="{ date, ...n } in month"
    v-text="date"
    :class="[ 'day', n ]"
  ></div>
</div>

.calendar {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Adamos
@Adamos
Нет в этом цикле никакой проблемы. Проблема в логике.
Там должен быть день недели первого числа, а у вас - тупо первое число, единица. Соответственно, перед ним втыкается один пробел независимо от того, с какого дня начинается месяц.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы