BLOG

ブログ

Vue3 + FullCalendarでカスタムカレンダーを作ってみた〜基本編〜

こちらは、Mavs Advent Calendar 2024 5日目の記事です🐺!

🌲🌲🌲

はじめまして!10月に入社した増田です。

ブログ初投稿記事は、最近プロジェクトで活用したFullCalendarについて記載します!

FullCalendarとは?

FullCalendarとは、カレンダー機能を簡単かつ自由にカスタマイズして導入できるJavaScriptのオープンソースライブラリです。

300以上のカスタマイズ設定があり基本的には無償で使用できますが、一部は有償ライセンスが必要なPremium機能となっています。ただし、評価目的(商用目的はNG)であれば試しに使用することが可能です!(※詳しくは公式ドキュメントをご確認ください。)

プロジェクトではVue2 + FullCalendarでカレンダーを実装しましたが、今回の記事ではVue3 + FullCalendarを使用し基本的なカレンダーの作成手順と、Premium機能の導入についてご紹介します。

私自身がVue3初心者かつFullCalendarもまだまだ不慣れなため、今回は初心者向けの基本編として記載していきます。

完成形はこちら

完成イメージ
完成イメージ

実装内容&環境

vue3.5.13
fullcalendar/vue36.1.15
fullcalendar/core6.1.15
fullcalendar/timegrid6.1.15
fullcalendar/resource6.1.15
※FullCalendarのプラグインは、使用するものを適宜追加していきますが、今回は全てVer.6.1.15のものを使用します。

実際のプロジェクトでは、もともと基本的なプラグインでカレンダーを作成していたところに、機能追加でPremium機能のresourceを使用することになり、追ってresoureceプラグインをインストールしました。

その際、coreプラグインとresourceプラグインとでバージョンに差が出てしまい、依存関係のエラーでうまくインストールできないことがありました。その場合は、必要に応じてcoreプラグインなども一緒に最新バージョンへ更新するまたは追加する側のプラグインのバージョンを他と同じものに指定することで解消しました。

今回のように最初から複数のプラグインを同時にインストールする場合は特に関係ないのですが、もし上記のようにタイムラグがある時は注意が必要です。

プロジェクト作成~カレンダー配置まで

まずは適当なVue3のプロジェクトを作成し、FullCalendar導入に必要なものをインストールします。プロジェクトのルートディレクトリで下記のコマンドを実行します。

npm install --save \
  @fullcalendar/core \
  @fullcalendar/vue3

※Vue2とVue3とでコマンドが違うので注意です!

上記に追加して、使用したいプラグインもいくつかインストールします。

npm install --save @fullcalendar/core @fullcalendar/timegrid @fullcalendar/daygrid
  • time-grid → 時間単位のスケジュールを表示したい時向けのビュー
  • day-grid → イベントを日付ごとに表示したいとき向けのビュー

package.jsonに下記が追加されていたら成功です。

package.jsonの中身
package.jsonの中身

次に、カレンダーを配置します。App.vueを下記のように記載します。

<template>
  <FullCalendar :options="calendarOptions" /> // カレンダー本体
</template>
<script setup lang="ts">
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
const calendarOptions = {
  plugins: [dayGridPlugin, timeGridPlugin], // 表示形式のプラグイン
  initialView: 'dayGridMonth', // 初期表示形式の設定
}
</script>
配置後の初期カレンダー
配置後の初期カレンダー

見た目はさておき、このように表示されていたら、一旦はカレンダー配置まで完了です!

見た目をカスタムしてみる

現状は英語表記だったりカレンダー自体が小さく見づらいので、色々見た目をカスタマイズします。

まずはカレンダー自体のサイズを変更します。

calendarOptionsにheightを設定するといい感じに見やすくなりました。※ついでにプロジェクト作成時のデフォルト文字色なども変更しました。

height: 'auto',
高さを整えたカレンダー
高さを整えたカレンダー

ちなみに高さ設定にはheightとcontentHeightがあり、前者はヘッダー・フッターを含むカレンダー全体の高さを設定したい時、後者はカレンダーの表示領域の高さを設定したい時という用途になっています。

似たような設定プロパティが多いので、公式ドキュメントを読みつつ、用途にあったものを選びましょう!

次にヘッダー部分を変更します。上記で表示されているdayGridの他に、timeGridのプラグインもインストールしていますので、そちらを表示してみます。

headerToolbar: {
    start: 'today prev,next',
    center: 'title',
    end: 'dayGridMonth,timeGridWeek,timeGridDay',
  },

上記をcalendarOpstionsに追加すると、下記のようになりました。

ヘッダーを設定したカレンダー
ヘッダーを設定したカレンダー

start/center/endの順ですが、向かって左側/真ん中/右側に、それぞれ配置したいものを記載するだけです。

dayGridMonth/timeGridWeek/timeGridDayといった表示タイプについても、記載した順で配置されます!

次に、カレンダー表記が英語になっているので、日本語に変更します。import文を追加し、calendarOptionsにlocaleを追加します。

import jaLocale from '@fullcalendar/core/locales/ja'
const calendarOptions = {
  plugins: [dayGridPlugin, timeGridPlugin],
 …
   // 〜省略〜
  locale: jaLocale,
}
日本語化したカレンダー
日本語化したカレンダー

このように、ヘッダーからカレンダー自体の表示まで、日本語に変更することができました!

Premium機能を導入してみる

Premium機能には下記があり、冒頭にも記載した通り使用するには有償ライセンスが必要です。ですが今回は評価目的としてPremium機能を試してみます。

Timeline View多数のリソースを、日付/時刻を横方向に表示する 
Vertical Resource Viewリソースを列として表示する
Print Optimization印刷時のカレンダーの見栄えを最適化する
※詳細は各リンクから公式ドキュメントをご覧ください。

例えば、timeGridDayだと一日の時間単位でイベントを表示しますが、どちらかというと一日かつ複数の人物や場所の予定を時間単位で確認することが多いのではないかなと個人的には思います!

今回使いたいVertical Resource Viewはまさに上記のような用途に適しており、複数のリソースを列表示できるので、こちらをインストールしていきます!

npm install --save \
  @fullcalendar/core \
  @fullcalendar/resource \
  @fullcalendar/resource-timegrid

次に、App.vueにプラグインをimportし、表示したいリソースを追加します。この時、日の表示形式でリソースを表示したいので、ヘッダーのtimeGridDayをresourceTimeGridDayに置き換えます。

現在のscriptは下記のようになっています!

<script setup lang="ts">
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import jaLocale from '@fullcalendar/core/locales/ja'
import resourceTimeGridPlugin from '@fullcalendar/resource-timegrid'

const calendarOptions = {
  schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives', // Free Trialのライセンスキー
  locale: jaLocale,
  plugins: [dayGridPlugin, timeGridPlugin, resourceTimeGridPlugin],
  initialView: 'resourceTimeGridDay',
  height: 'auto',
  stickyHeaderDates: true,
  headerToolbar: {
    start: 'today prev,next',
    center: 'title',
    end: 'dayGridMonth,timeGridWeek,resourceTimeGridDay',
  },
  resources: [
    { id: 'roomA', title: '会議室A' },
    { id: 'roomB', title: '会議室B' },
    { id: 'roomC', title: '会議室C' },
    { id: 'roomD', title: '会議室D' },
  ],
}
</script>

日の表示を確認すると、このようにリソースを表示することができました!🎉

リソースを追加したカレンダー
リソースを追加したカレンダー

ちなみに、しれっと追加しているschedulerLicenseKeyですが、記載がなくてもPremium機能を試すことはできます。ただ、下記のようにライセンスの警告が表示されるので、気になる場合は公式ドキュメントにあるキーを追加するだけで非表示にすることができます!

では次に、何も予定がないのもカレンダーぽくないので、ハードコーディングですがイベントを追加してみましょう。

イベントを追加してみる

イベントの設定プロパティで基本的なものとして、イベントタイトル・開始日時・終了日時・終日設定があります。

今回はリソースも設定しているので、resourceIdに先ほど追加したリソースのIDを記載します。

<script setup lang="ts">
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import jaLocale from '@fullcalendar/core/locales/ja'
import resourceTimeGridPlugin from '@fullcalendar/resource-timegrid'

const calendarOptions = {
  schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
  locale: jaLocale,
  plugins: [dayGridPlugin, timeGridPlugin, resourceTimeGridPlugin],
  initialView: 'resourceTimeGridDay',
  height: 'auto',
  stickyHeaderDates: true,
  headerToolbar: {
    start: 'today prev,next',
    center: 'title',
    end: 'dayGridMonth,timeGridWeek,resourceTimeGridDay',
  },
  resources: [
    { id: 'roomA', title: '会議室A' },
    { id: 'roomB', title: '会議室B' },
    { id: 'roomC', title: '会議室C' },
    { id: 'roomD', title: '会議室D' },
  ],
  events: [ // ここから追加。多いので一部イベントは省略
    {
      title: 'MAVS ADVENT CALENDAR START🎄🎉',
      start: '2024-12-01',
      end: '2024-12-01',
      resourceId: 'roomA',
    },
    {
      title: 'ますだ記事投稿日📝',
      start: '2024-12-05',
      end: '2024-12-05',
      resourceId: 'roomB',
    },
    {
      title: 'イベント',
      start: '2024-12-05T09:00:00',
      end: '2024-12-05T10:30:00',
      resourceId: 'roomC',
    },
    {
      title: '旅行🏖️',
      start: '2024-12-14',
      end: '2024-12-17',
      allDay: false,
    },
  …
  ],
}
</script>

<style scoped lang="scss">
.calendarWrap {
  width: 100%;
  height: 100%;
  max-height: 75vh;
  overflow-y: scroll;
}
</style>
複数のイベントを追加すると、このような感じでようやくちゃんとしたカレンダーになりました!
これで完成です。
月表示
月表示

週表示
週表示

日表示(リソース)
日表示(リソース)

まとめ

今回は基本編として、カレンダーの作成手順とPremium機能の導入について記載しました。表示するだけならとても簡単に作成することができ、いろんな設定ができるのもFullCalendarの魅力だと思います。

ただ、細かいスタイルを設定したい場合、該当する設定プロパティがないものも多いので、その際はFullCalendarの要素のクラス名を確認しつつ、スタイルを当てていくことになります。ちょっと手間ですが、見た目にもこだわりたい時はこの方法でアレンジできます。

実際にプロジェクトで使用する際は、APIからのイベントデータをFullCalendarに表示したり、FullCalendarからイベントを登録/編集もできます。イベントの日時をドラッグ&ドロップで移動できたり、リサイズして変更したり、、、

また、Google Calendarと連携して予定を表示することもできますので、今回触れなかった機能に関しては今後試してみたいと思います!

RELATED ARTICLE

  • この記事を書いた人
  • 最新の記事

konami-masuda

2024年10月に入社した増田です!ねこが好き!