«Vue3+Typescript» — простая реализация компонента календаря.

Это front-end блоггер без рутины.Он увлекается всеми видами front-end ориентированных операций.Он часто пишет то,что думает.Если вас интересуют технологии и front-end эффекты,то можете оставить сообщение~ Блогер наступит на яму для всех, увидев это.

Домашняя страница: Домашняя страница Оливера Иня

Девиз: Вставай, когда падаешь~

Оглавление

Введение

2. Рендеринг

3. Основные идеи

4. Реализация кода

4.1 Расчет числа этого месяца

4.2 Завершите дату предыдущего месяца

4.3 Завершение даты следующего месяца

4.4 Преобразование в двоичный массив

4.5 Использование v-for для создания календаря

4.6 Лунный календарь, праздники и т.д.

V. Резюме


Введение

Недавно в проекте нужно было использовать компонент календаря.Поскольку я искал и не нашел подходящего, то решил сделать его сам.Проект должен быть сложнее этого.Вот только идея или направление развития за каждого маленького партнера. ~

После терпеливого прочтения вы можете что-то обрести... (PS: Если вы хотите оставить исходный код с адресом электронной почты, блоггер пришлет его после просмотра~)

2. Рендеринг

Общая схема эффекта выглядит следующим образом:

3. Основные идеи

Лично ядром календаря является  вычисление дня недели в первый день указанного месяца Почему? Потому что, с точки зрения формы, календарь отображается как такой прямоугольник 7 * 6. Если вы знаете день недели 1-го числа, вы можете заполнить дату до 1-го числа, а также можете заполнить дату после последний день.;

Поэтому расчет календаря можно разделить на три раздела:

  • Первый пункт, расчет этого месяца, вычисляет текущий день недели 1 числа, а затем вычисляет общее количество дней в этом месяце;
  • Второй пункт, рассчитанный в прошлом месяце, подсчитывает общее количество дней до 1 числа;
  • Третий абзац, расчет следующего месяца, вычисляет общее количество дней после этого месяца;

Таким образом, три сегмента соединяются вместе, чтобы сформировать полный набор текущих массивов.Если непонятно, давайте приведем другой пример.В качестве примера возьмем июль 2023.1 июля - суббота, поэтому он должен быть в прямоугольник это положение

Затем должно быть 6 дней до субботы, а последние 6 дней июня нужно использовать для завершения первой половины прямоугольника ;

Затем вычислить последний день июля, 31 июля понедельник, тогда он должен быть в этом положении

Такой полный прямоугольник (календарь) является полным с точки зрения данных;

4. Реализация кода

4.1 Расчет числа этого месяца

Расчет даты этого месяца делится на две части: первая часть - получение текущей даты , а вторая часть - получение недели 1-го числа этого месяца.

Сначала получите текущую дату

// 获取当前日期
function getCurrent() {
    const date = new Date();
    return [date.getFullYear(), date.getMonth() + 1, date.getDate()];
}

Сначала получите в этом месяце, очень просто

/**
 * 获取公历某一天是星期几
 * @param {number} y 年
 * @param {number} m 月
 * @param {number} d 日
 * @returns {number} 返回星期数字[0-6]
 */
function solarWeek(y: number, m: number, d: number) {
  let date = new Date(y, m - 1, d);
  let week = date.getDay();
  return week;
}

const currentDate = getCurrent()
// 使用
this.solarWeek(currentDate[0], currentDate[1], 1)

Таким образом, мы получаем день первого дня;

4.2 Завершите дату предыдущего месяца

Одна вещь, которую следует отметить в отношении сбора данных за предыдущий месяц, заключается в том, что если текущим месяцем является январь, то необходимо получить декабрь предыдущего года, поэтому текущий месяц необходимо определить перед расчетом.

// 判断年度
const y = date[1] === 1 ? date[0] - 1 : date[0];
// 判断月份
const m = date[1] === 1 ? 12 : date[1] - 1;

Следующим шагом является оценка количества дат, которые необходимо выполнить. Это очень просто. Нам нужно только судить по дню недели. Если это суббота, то это 6 дней (с понедельника по пятницу, плюс Воскресенье), если это пятница, то это составляет 5 дней (с понедельника по четверг плюс воскресенье);

 /**
   * 获取当月前面需补齐的数组
   */
beforDays(date: number[], last: number) {
    const y = date[1] === 1 ? date[0] - 1 : date[0];
    const m = date[1] === 1 ? 12 : date[1] - 1;

    const arr: dateBase[] = [];
    for (let i = 0; i < last; i++) {
        arr.push({...});
    }
    return arr;
}

Это последняя неделя 1-го, это количество циклов, которые необходимо повторить;

4.3 Завершение даты следующего месяца

Затем составить следующий месяц, который аналогичен расчету предыдущего месяца.Во-первых, необходимо судить, является ли это декабрь.Если это декабрь, то следующий месяц является январем следующего года.

const y = date[1] === 12 ? date[0] + 1 : date[0];
const m = date[1] === 12 ? 1 : date[1] + 1;

Затем, так как мы знаем количество дней в текущем месяце и количество дней, пройденных в предыдущем месяце, мы можем естественным образом подсчитать, сколько дней нужно выполнить в следующем месяце, 42-количество дней в текущем месяце -количество дней в предыдущем месяце = количество дней в следующем месяце количество дней ;

/**
 * 获取当月后面需补齐的数组
 */
afterDays(day: dateBase[], date: number[]) {
    const arr: dateBase[] = [];
    const y = date[1] === 12 ? date[0] + 1 : date[0];
    const m = date[1] === 12 ? 1 : date[1] + 1;

    for (let i = 1; i < 42 - day.length + 1; i++) {
        arr.push({...});
    }
    return [...day, ...arr];
}

На данный момент мы можем получить массив длиной 42 , который представляет в общей сложности 42 дня с последнего дня прошлого месяца до этого месяца, а затем до положительного дня следующего месяца;

4.4 Преобразование в двоичный массив

Причина преобразования его в двузначный массив очень проста, потому что наш календарь представляет собой двузначный массив с точки зрения макета.Всего 6 строк, и каждая строка имеет 7 сеток, верно, поэтому нам нужно преобразовать это, Код для поворота тоже очень простой

const dateArray = [];
for (let row = 0; row < 6; row++) {
    dateArray.push(allDate.splice(0, 7));
}

4.5 Использование v-for для создания календаря

После того, как базовая сортировка данных завершена, вам нужно только генерировать сетки партиями с помощью команды Vue v-for;

<template v-if="TBody.length">
  <div
    class="t-calendar-row"
    v-for="(item, index) in TBody"
    :key="index"
    >
    <div
      class="t-calendar-col"
      v-for="(col, colIdx) in item"
      :key="colIdx"
      >
      <CalendarItem
        :col="col"
        :time="selectedTime"
        @changeTargetDate="changeDate"
        ></CalendarItem>
    </div>
  </div>
</template>
<template v-else>
  <div class="no-date">抱歉,暂无数据</div>
</template>

Что касается стиля каждой сетки, его можно настроить в соответствии с потребностями;

4.6 Лунный календарь, праздники и т.д.

Реальный календарь должен быть намного больше, чем эти основные данные, а также должен включать в себя: лунный календарь, фестивали, праздники и т. д. различные отметки, которые можно рассчитать вместе со значением, соответствующим текущей дате, и отобразить через v-for It. достаточно для рендеринга соответствующего стиля CSS в любое время, например, при выполнении push данных:

arr.push({
  // 日期
  title: w - i,
  // 是否本月
  isCurrent: false,
  // 是否节假日
  isHolidays: DateClass.getHolidays([y, m, w - i]),
  date: `${y}-${clockFactory(m)}-${clockFactory(w - i)}`,
  // 阴历
  lunars: lun,
  isNow: false,
  // 阳历节日,如国庆,元旦
  solarDay: DateClass.getSolarDay(m, w - i),
  // 农历节日,如中秋,春节,端午
  lunarDay: DateClass.getlunarDay(Number(l[0]), Number(l[1]), Number(l[2])),
  // 生肖
  animal: DateClass.getAnimal(Number(l[0])),
  // 星座
  astro: DateClass.toAstro(y, m, w - i),
  // 节气
  term: getTerm(Number(l[0]), m, w - i)
});

И так далее можно обрабатывать вместе при обработке данных;

V. Резюме

Фактически, после того, как я узнал принцип генерации календаря, я действительно чувствую, что календарь не так уж и сложен в реализации, но это немного хлопотно, и окончательная реализация должна определяться в соответствии с фактическими потребностями;

Supongo que te gusta

Origin blog.csdn.net/zy21131437/article/details/131995484
Recomendado
Clasificación