当記事は公開されてから 3 年以上経過している記事です。
「アドベントカレンダーを自作する」の改善提案など気軽にご協力いただければ幸いです。
Issue はこちらでよろしくお願いします:
俺だけアドベントカレンダーとは、
Qiita のアドベントカレンダーでもいくつか書かせていただく予定ですが、それ以外でも技術ネタを発信したいと考え、当ブログに俺だけアドベントカレンダー 専用ページを作りました。
この年末恒例特別なイベントという印象がありますが、基本的にはカレンダーを作れば良いのです。当ブログでは既に Vuex ストアでブログのコンテンツ情報が格納されています。ブログのリンク先を各日に設定、1 日から 25 日まで公開することで大方の目的は達成します。
曜日から開始、終了位置を求める
日付操作には moment より軽量の dayjs
を使います。
const startDay = dayjs(`${this.year}/12/01`).format('dddd')
キモは開始日 12 月 1 日の曜日を確認することです。日曜日の場合は 0、月曜日の場合は 1 のように、開始位置を求めます。
const endDay = dayjs(`${this.year}/12/31`).format('dddd')
この開始位置は、月が始まるまでの余白を設定する際に役立ちます。同様に終了日 12 月 31 日の曜日も確認し、終了位置を求めます。
Gridレイアウトを利用する
カレンダー全体を囲う要素に対して display: grid;
を指定。
.calendar {
display: grid;
width: 100%;
grid-template-columns: repeat(7, minmax(20px, 1fr));
grid-template-rows: 50px;
grid-auto-rows: 120px;
overflow: auto;
}
その子要素を 7 行ずつループさせれば OK 25 日まで日付の他にアイコンを表示。26 日以降についてはアドベントカレンダーの決まりにより、ブログ記事のリンクと紐付けできないよう日付のみを表示するようにしました。
.day img {
opacity: 100%;
}
該当日の記事が投稿され次第、アイコンの opacity を 100%にし、そのリンク先へ飛べるようにします。
開始、終了位置をここで使う
先ほど求めた開始位置や、終了位置をどこで使うのか。
<div
v-for="i in startOfMonth"
:key="i"
class="day day--disabled"
/>
2019 年 12 月こそ日曜日からスタートしますが、毎月必ず日曜日から始まる訳ではありません。ですがカレンダーの並びとしてこの日曜日から始めなければならず、開始位置(または終了位置)がキモになるという訳です。
詳しくは
ソースコードを確認してください。
あとは容易に動的ページに載せるだけ。 pages/advent-calendar/
に _year.vue
を作成し、Route パラメータに該当年を指定します。
async asyncData({ route }) {
await store.dispatch('product/fetchPost', {
'slug': '',
'month': `${route.params.year}-12`
})
}
最後のキモは Route パラメータ route.params.year
を使ってアクセスしていること。
既に Vuex ストアでコンテンツ情報を取得しており、今回もブラウザのレンダリング前に該当する年のコンテンツ情報を取得すべく asyncData で呼び出した。
ここだけの話、来年以降も使えます
該当年を入れるようにしたことで以後使えるようになります。