シンプルなカレンダーコンポーネント実装「Vue3+Typescript」

これはルーチンのないフロントエンドブロガーです。彼はあらゆる種類のフロントエンド指向の操作に熱心です。彼は思いついたときにどこでもよく書きます。テクノロジーとフロントエンド効果に興味がある場合は、メッセージを残してください〜ブロガーそれを見た後、全員のためにピットを踏みます。

ホームページ:オリバー・インのホームページ

座右の銘:転んでも起き上がれ〜

目次

I.はじめに

2. レンダリング

3. 核となるアイデア

4. コードの実装

4.1 今月の日付の計算

4.2 前月の日付を入力します

4.3 翌月の日付を記入する

4.4 バイナリ配列への変換

4.5 v-for を使用してカレンダーを生成する

4.6 旧暦、祝日等

V. まとめ


I.はじめに

最近、プロジェクトでカレンダー コンポーネントを使用する必要がありました。探しても適切なものが見つからなかったので、自分で作成することにしました。プロジェクトはこれよりも複雑になるはずです。ここにアイデアまたは開発の方向性を示します。それぞれの小さなパートナーのために。〜

辛抱強く読んでいくと、何か得られるかもしれません... (追記: ソースコードをメールアドレスに残したい場合は、ブロガーがそれを見て送信します~)

2. レンダリング

一般的な効果図は次のとおりです。

3. 核となるアイデア

個人的には、カレンダーの中心は、 指定した月の 1 日の曜日を計算することです。なぜですか? 形式的には、カレンダーは 7*6 の長方形として表示されるので、1 日の曜日がわかっていれば、1 日より前の日付を記入することもできますし、1 日以降の日付を記入することもできます。最終日。

したがって、カレンダーの計算は 3 つのセクションに分けることができます。

  • 最初の段落である今月の計算では、1 日の現在の曜日を計算し、次に今月の合計日数を計算します。
  • 2 番目の段落は先月計算され、1 番目の段落までの合計日数をカウントします。
  • 3 番目の段落、来月の計算では、今月以降の合計日数を計算します。

このようにして、3 つのセグメントが接続されて、現在の配列の完全なセットが形成されます。明確でない場合は、別の例を示します。例として 2023 年 7 月を取り上げます。7 月 1 日は土曜日なので、この位置を四角形にします

次に、土曜日までに 6 日間あるはずで、長方形の前半を完成するには 6 月の最後の 6 日間を使用する必要があります

次に、7 月の最終日を計算します。7 月 31 日は月曜日なので、この位置になるはずです。

このような完全な長方形 (カレンダー) は、データの観点から見ると完全です。

4. コードの実装

4.1 今月の日付の計算

今月の日付の計算は 2 つの部分に分かれており、最初の部分では現在の日付を取得し、2 番目の部分では今月 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 前月の日付を入力します

前月のデータ取得について注意すべき点は、現在の月が 1 月の場合、前年の 12 月が取得されるため、計算する前にまず現在の月を決定する必要があることです。

// 判断年度
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 翌月の日付を記入する

翌月は前月の計算と同じで、まず12月かどうかを判断する必要があり、12月であれば翌月は翌年の1月となります。

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 バイナリ配列への変換

2 桁の配列に変換する理由は非常に単純です。カレンダーはレイアウト上 2 桁の配列なので、合計 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 スタイルをレンダリングするには十分です。

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. まとめ

実際、暦の生成原理を知った後、暦の実装はそれほど難しくないと感じていますが、少し面倒で、最終的な実現は実際のニーズに応じて決定する必要があります。

おすすめ

転載: blog.csdn.net/zy21131437/article/details/131995484