15
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

Nuxt.jsでカレンダープラグイン「Fullcalendar」を使ってみた

Nuxt.jsでカレンダー予定管理機能を導入

なにかいいものはないかと探していたら、fullcalendarを見つけた。jQueryに依存していないV4のbeta版がでているとのことでそちらを今回導入してみました。
※予定では3月15日に正規版がリリースされるみたいです。

ソース
https://github.com/sauzar18/fullcalendar-v4-nuxt

環境

Nuxt.jsを導入

公式ドキュメント参照
Nuxt.js

こちらから導入方法がわかります。

backpack-coreの設定は下記参照
https://qiita.com/sauzar18/items/32a8553587e2bdcf3689

1.Fullcalendarベースのモジュールをインストール

yarn add @fullcalendar/core @fullcalendar/daygrid

これを導入すると下記ができるようになります。

ここから追加したい機能に応じてモジュールをインストールしていきます。

今回は下記をインストールしました。

  • moment.jsの特徴を引き継いでいるmomentプラグイン
  • 時間ごとに予定が管理できるtimegridプラグイン
  • データのやり取り(クリックアクションでデータをゲットするなど)interactionプラグイン
yarn add @fullcalendar/moment @fullcalendar/timegrid @fullcalendar/interaction

インストール完了したらvueファイルの設定

2. Vueファイル設定

pages/index.vue
<template>
  <div>
    <main>
      <div id="calendar" />
    </main>
  </div>
</template>
<script>
export default {
  head() {
    return {
      link: [
        { rel: 'stylesheet', href: '/css/fullcalendar.min.css' }
      ]
    }
  },
  data() {
    return {
      events: [
        { title: 'event1', start: '2019-02-27' },
        { title: 'event2', start: '2019-02-28T12:00', end: '2019-02-28T14:00' },
        { title: 'event3', start: '2019-02-28T12:30:00', allDay: false }
      ]
    }
  },
  created() {
    this.$store.commit('setEvents', this.events)
  }
}
</script>

こんな感じでVueファイルを設定していきます。

Rest apiなどasync awaitを使ってeventsデータを読み込んだ方が実用的なので、その方法も記載

pages/index.vue
<template>
  <div>
    <main>
      <div id="calendar" />
    </main>
  </div>
</template>
<script>
export default {
async asyncData ({ app, store, params }) {
    const data = await app.$axios.$get(`/api/get_schedule/${store.state.authUser.userid}`)
    store.commit('setEvents', data)
  },
  head() {
    return {
      link: [
        { rel: 'stylesheet', href: '/css/fullcalendar.min.css' }
      ]
    }
  }
}
</script>

ここでやっていることは

  • カレンダーを表示する箇所にidを設置
  • イベントデータを読み込んでstoreで状態管理
  • fullcalendarのインストール版に入っているcssを読み込む

3. storeの設定

store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
export const state = () => ({
  events: null
})
export const mutations = {
  setEvents(state, data) {
    state.events = data
  }
}

4. pluginsでfullcalendarを読み込み

plugins/calendar.js
import { Calendar } from '@fullcalendar/core'
import dayGridPlugin from '@fullcalendar/daygrid'
import momentPlugin from '@fullcalendar/moment'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import jaLocale from '@fullcalendar/core/locales/ja' // 日本語に対応させるために読み込む
export default function (context) {
  if (document.querySelector('#calendar')) {
    document.addEventListener('DOMContentLoaded', function () {
      const calendarEl = document.querySelector('#calendar')
      const calendar = new Calendar(calendarEl, {
        locale: jaLocale,
        height: 625,
        events: context.store.state.events,
        plugins: [dayGridPlugin, momentPlugin, timeGridPlugin, interactionPlugin],
        defaultView: 'dayGridMonth',
        editable: true,
        selectable: true,
        selectHelper: true,
        ignoreTimezone: false,
        header: {
          left: 'today prev,next',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek,timeGridDay'
        },
        eventLimit: true,
        firstDay: 0,
        weekends: true,
        weekMode: 'fixed',
        weekNumbers: false,
        slotDuration: '00:30:00',
        snapDuration: '00:15:00',
        allDaySlot: false,
        allDayText: 'allday',
        slotMinutes: 15,
        snapMinutes: 15,
        slotLabelFormat: 'H:mm',
        firstHour: 9,
        defaultTimedEventDuration: '10:00:00',
        axisFormat: 'H:mm',
        timeFormat: 'H:mm',
        minTime: '00:00:00',
        maxTime: '24:00:00',
        buttonText: {
          prev: '',
          next: '',
          prevYear: '',
          nextYear: ''
        },
        eventClick: function (info) {
          alert('Event: ' + info.event.title)
          alert('Coordinates: ' + info.jsEvent.pageX + ',' + info.jsEvent.pageY)
          alert('View: ' + info.view.type)
          // change the border color just for fun
          info.el.style.borderColor = 'red'
        },
        dateClick: function (info) {
          alert('Clicked on: ' + info.dateStr)
          alert('Coordinates: ' + info.jsEvent.pageX + ',' + info.jsEvent.pageY)
          alert('Current view: ' + info.view.type)
          info.dayEl.style.backgroundColor = 'red'
        }
      })

      calendar.render()
    })
  }
}

ここでやっていること

  • モジュールをimport
  • 日本語対応
  • storeを使えるようにexport defaultをつかう
  • id(#calendar)があるページのみスクリプトが着火
  • 公式ドキュメント通りに各種設定

locale

言語設置

height

コンテンツの高さの設定

events

イベント情報の設定

plugins

利用するモジュールの設置

defaultview

デフォルトの表示設定

editable

カレンダーの予定を変更できるかどうか

selectable

クリックしてドラッグすることで、ユーザーが複数の日またはタイムスロットを強調表示できるようにする

selectHelper

ユーザーがドラッグしている間に「プレースホルダー」イベントを描画するかどうか。

ignoreTimezone

UTCオフセットを無視するかどうか

header

カレンダーの上部にあるボタンとタイトルを定義

eventLimit

1日に表示されるイベントの数を制限。残りはポップオーバーに表示。

firstDay

毎週始まる日の設定。
日曜日= 0、月曜日= 1、火曜日= 2など

weekends

土曜日/日曜日の列をいずれかのカレンダービューに含めるかどうか。

weekMode

月ビューに表示される週数を決定

weekNumbers

週番号をカレンダーに表示するかどうか

slotDuration

タイムスロットを表示する頻度。

snapDuration

ドラッグされたイベントが時間軸にスナップする時間間隔。

allDaySlot

「終日」スロットをカレンダーの上部に表示するかどうか

allDayText

カレンダー上部の「終日」のスロットにタイトルを付けるテキスト

slotMinutes

タイムスロットを表示する頻度(分単位)。

snapMinutes

ドラッグされたイベントがアジェンダビューのタイムグリッドにスナップする間隔。

slotLabelFormat

タイムスロット内に表示されるテキスト

firstHour

スクロール区画に表示される最初の1時間を決定

defaultTimedEventDuration

値が指定されていない時限イベントオブジェクトのフォールバック期間

axisFormat

アジェンダビューの垂直軸に表示されるタイムテキストを決定

timeFormat

各イベントに表示される時間テキストを決定

minTime

毎日表示される最初のタイムスロットを決定

maxTime

毎日表示される最後のタイムスロットを決定

buttonText

ヘッダー/フッターのボタンに表示されるテキスト

eventClick

ユーザーがイベントをクリックしたときに発生

※ここでquerySelectorなどをつかって値を入れてもいいし、試してないけど、storeにいれた管理してもよいかと

dayClick

ユーザーが日付または時刻をクリックしたときに発生

他にも設定できることは沢山あります。詳しくはDoc参照

5. nuxt.config.js設定

pluginの読み込み

nuxt.config.js
plugins: [
    { src: '~/plugins/calendar.js', ssr: false }
],

eslintなどでfullcalendarが使えない場合

nuxt.config.js
build: {
    /*
    ** You can extend webpack config here
    */
    extend(config, ctx) {
        // Run ESLint on save
        if (process.server && process.browser) {
        config.module.rules.push({
            enforce: 'pre',
            test: /\.(js|vue)$/,
            loader: 'eslint-loader',
            exclude: /(node_modules)/
        })
        }
    }
}

これでカレンダーが表示されれば設置完了です。

まとめ

v4の本リリース後またソースの修正が必要になると思う

storeを使ってフロントに描写するかdocument.querySelectorなどDOMの操作を使って描写するといいかも

もっといい方法があるかもしれないのである方は共有お願いします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
15
Help us understand the problem. What are the problem?