2015/07/30

【JavaScript】Vue.jsでカレンダーをつくる

ライフログアプリには欠かせないカレンダーをVue.jsを使って実装してみた。
基本的なカレンダーのつくり方は、Vue.jsとかAngularJSとかフレームワークに関係なく使えると思う。
ということで、さっそく実装方法とまとめていく。



カレンダーをつくる



<!doctype html>
<html lang="ja">
<head>
  <meata charset="utf-8">
  <title>Vue.jsでカレンダーを実装する</title>
  <link href="style.css" rel="stylesheet">
</head>
<body>
  <div id="app">
      <div id="calendar-nav">
          <i class="glyphicon glyphicon-menu-left" v-on="click: moveLastMonth"></i>
          <span>{{calData.year}} - {{getMonthName(calData.month)}}</span>
          <i class="glyphicon glyphicon-menu-right"  v-on="click: moveNextMonth"></i>
      </div>
      <table id="calendar" class="table table-bordered">
          <thead>
              <tr>
                  <th v-repeat="week: weeks">{{week}}</th>
              </tr>
          </thead>
          <tbody>
              <tr v-repeat="week: calendar">
                  <td v-repeat="day: week">{{day.day}}</td>
              </tr>
          </tbody>
      </table>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.8/vue.min.js"></script>
  <script src="index.js"></script>
</body>
</html>

/* カレンダーナビのスタイル */
#calendar-nav {
    text-align: center;
}

#calendar-nav span {
    display: inline-block;
    width: 200px;
}

#calendar-nav i:hover {
    cursor: pointer;
}

/* カレンダーのスタイル */
.table th, td{
    text-align: center;
}

#calendar th:first-child {
    background-color: #FEEEFF;
}
#calendar td:first-child {
    background-color: #FEEEFF;
}
#calendar th:nth-child(7) {
    background-color: #DFFFFF
}
#calendar td:nth-child(7) {
    background-color: #DFFFFF
}

#calendar td:hover {
    opacity: 0.6;
}

new Vue({
    el: '#app',
    data: {
        weeks: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
        calData: {year: 0, month: 0}
    },
    created: function (){
        var date = new Date();
        this.calData.year = date.getFullYear();
        this.calData.month = date.getMonth() + 1;
    },
    methods: {
        getMonthName: function(month) {
            var monthName = ['January','February','March','April','May','June','July','August','September','October','November','December'];
            return monthName[month - 1];
        },
        moveLastMonth: function() {
            if (this.calData.month == 1) {
                this.calData.year--;
                this.calData.month = 12;
            }
            else {
                this.calData.month--;
            }
        },
        moveNextMonth: function() {
            if (this.calData.month == 12) {
                this.calData.year++;
                this.calData.month = 1;
            }
            else {
                this.calData.month++;
            }
        }
    },
    computed: {
        calendar: function () {
            // 1日の曜日
            var firstDay = new Date(this.calData.year, this.calData.month - 1, 1).getDay();
            // 晦日の日にち
            var lastDate = new Date(this.calData.year, this.calData.month, 0).getDate();
            // 日にちのカウント
            var dayIdx = 1;

            var calendar = [];
            for (var w = 0; w < 6; w++) {
                var week = [];

                // 空白行をなくすため
                if (lastDate < dayIdx) {break;}

                for (var d = 0; d < 7; d++) {
                    if (w == 0 && d < firstDay) {
                        week[d] = {day: ''};
                    } else if (w == 6 && lastDate < dayIdx) {
                        week[d] = {day: ''};
                        dayIdx++;
                    } else if (lastDate < dayIdx) {
                        week[d] = {day: ''};
                        dayIdx++;
                    } else {
                        week[d] = {day: dayIdx};
                        dayIdx++;
                    }
                }

                calendar.push(week);
            }
            return calendar;
        }
    }
});


カレンダーをつくる上で一番重要な処理は、computedのcalendarの処理。

firstDayで1日(いっぴ・ついたち)の"曜日"を取得する。
今月は何曜日から始まるのか、何曜日から1、2、3...と表示すればよいかを知るため。

lastDateは晦日(月の最終日)の"日にち"を取得する。
1日からはじめて、最終日までを表示するため。

ポイントとなるのは、52行目~65行目までの2重ループしているところ。
外のループはカレンダーの1行を表しており、内のループは1行に何日分表示するかを表している。


53行目は、カレンダーの1行目の処理。
55行目は、カレンダーの最終行の処理。
58行目は、カレンダー最終行の空白を埋めるための処理。
61行目は、1日~最終日までを表示する処理。


この他のmethodsのmoveLastMonthmoveNextMonthは、カレンダー上部の「<」「>」をクリックしたときに、先月・翌月に移動するための処理。



参考サイト




以上

written by @bc_rikko

0 件のコメント :

コメントを投稿