github にあげたくない場合は「.gitignore 」を活用する
はじめに
Nuxt
と Firebase
で練習アプリを作ったので、Github
にあげることにした。
しかし Github
にあげたくない情報(Firebase
のAPI
情報 etc)もあったので、それを除く方法を調べてみた。
.gitignore を使用する
調べてみると簡単で、.gitignore
というファイルを作り、フォルダにアップする。
そのファイルに除外するファイルを記述する。
ファイルの中身(基本)
# コメントを書く ファイル名
ファイルの中身(実例)
# Firebase の連携情報 firebase.js
テキストから距離を取ったボーダーを疑似要素以外で表現する
はじめに
今までテキストの下にボーダーを引く際、疑似要素を使用していたがもっと楽な方法を教えてもらった。
比較てみた
See the Pen rNWNLEO by PROGBLOG (@progblog-sank) on CodePen.
従来のやり方
// HTML <p class="past_way"><span>HELLO WORLD</span></p>
// SCSS .past_way { span { position: relative; &:before { content: ""; height: 1px; width: 100%; position: absolute; bottom: 0; left: 0; background-color: #EF5350 } } }
この書き方は慣れているので、特にどうとも思わないが、SCSS
で書くとき階層が深くなるため、わかりにくくなりがち。
新しいやり方
// HTML <p class="new_way"><span>HELLO NEW WORLD</span></p>
// SCSS .new_way { text-decoration-line: underline; text-decoration-color: #EF5350; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
こちらの方法はシンプルだが、ブラウザの互換性が気になる。
都度、調査する必要があるかもしれない。
IE で クラスをtoggleさせるには
はじめに
以前、classList
でクラスを操作する覚書をしたが、IE ではそのうちのtoggle()
が使えない沼に一瞬だけハマった。
解決方法
classList の.add() と .remove() 、そして contains() をうまく使えば解決する。
// HTML <p class="togglclassBtn">click me!</p> <p class="change_color">HELLO!</p>
// SCSS .togglclassBtn { display:inline-block; padding: 10px 20px; border-radius: 10px; box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; background-color: #EF5350; color: #FFFFFF } .change_color { display:inline-block; padding: 10px 20px; border-radius: 10px; box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; background-color: #FFFFFF; &.js-active { background-color: #1976D2; color: #ffffff; } }
// JavaScript const btn = document.querySelector('.togglclassBtn'); const target = document.querySelector('.change_color'); btn.addEventListener('click', function() { if(target.classList.contains('js-active')) { target.classList.remove('js-active') } else { target.classList.add('js-active') } })
See the Pen toggleClass by IE by PROGBLOG (@progblog-sank) on CodePen.
IE で動作確認は上記をダウンロードする。
Nuxt.js で v-for について理解を深める
はじめに
webアプリを開発中に v-for
についていまいち理解し切れていないと感じたので、じっくりと考えてみる。
なお、今回はCLI
ではなく CDN
にて動作確認をするので、すべてのソースに https://unpkg.com/vue@next を読み込んでいる。
まずは v-for ってなに
公式には下記のように書かれている。
v-for
ディレクティブを使えばアイテムのリストを配列内のデータを使って表示することができます
で例として挙げられてるのが、下記のようなソース。
See the Pen v-for_Base by PROGBLOG (@progblog-sank) on CodePen.
確かに配列を使用してデータを呼び出してくれている。
ただこれだけ見ると、別にHTML
にひとつひとつ書いていくのと決して変わらない。
むしろ面倒くさいと思うまである。
じゃあなぜ v-for を使用するのか
配列が動的に変化する場合は、非常に有効に作用する。
See the Pen JjRQyJw by PROGBLOG (@progblog-sank) on CodePen.
例えばこんな感じで、リストの増減する要素を簡単に作成することができる。
key属性 について
繰り返される DOM の内容が単純な場合や、性能向上のためにデフォルトの動作に意図的に頼る場合を除いて、可能なときはいつでも
v-for
にkey
属性を与えることが推奨されます。
上記にあるように、v-for
ではkey
属性を与えなければならない。
<ul> <li v-for="item in items" :key="item.id">...</li> </ul>
vue
のドキュメントにあるサンプルソースは上記の通り。
正直ここは理解しきれていないので、他サイトのまとめを拝借する。
key
はVue
の処理を手助けするkey
がない場合、同じ要素を再利用されるkey
がある場合、key
に基づいて変更される- 同じ要素を親に持つ場合
key
は一意なものにするv-for
のインデックスをkeyに用いないkey
を正しく用いて効率よく扱っていきましょう。
tanks🥰: Vue.jsのkeyとは?-Vue.js
Nuxt.js の dataメソッド で Date が管理できなかった
はじめに
Firebase に送ったデータの管理でタイムスタンプが必要になったので、データの送信時に現在時刻を送れるようにした。
やったこと
<template> <input type="hidden" v-model="checkTime"> </template> <script> export default { props: ["user"], data() { return { chekTime: new Date(), }; }, } </script>
このコードだと管理ができない。
対処方法
今回はユーザー側に見えるデータではなく、あくまでもタイムスタンプとして使用するので形式は問わない。
そのため、Date.now()
で管理することにして解決した。
Firebase のRealtime Database で取得した情報が重複しないようにする
はじめに
Firebase
の Realtime Database
から情報を取得し、 Nuxt.js の v-for
で表示させた。
初回はうまく読み込みのだが、新しくデータを追加し、.on
メソッドで呼び出したとき、今までのデータが1から呼び出され、過去のデータが2重に書き込まれた。
わかりにくいので、図のようにしてみる。
〇〇〇〇〇 ××××××××× △△△△△
に☆☆☆☆☆
を追加すると
〇〇〇〇〇 ××××××××× △△△△△ 〇〇〇〇〇 ××××××××× △△△△△ ☆☆☆☆☆
となる。
これを解決したい。
こうなったコード
created: function() { firebase.database().ref(this.user.uid).on("value", (snapshot) =>{ snapshot.forEach((childSnapshot) =>{ let childData = childSnapshot.val(); console.log(childData) this.details.push(childData); }) }) },
.on()
メソッドが発火されるたびに、実行される。
またvalue
は下記の通り。
イベントの種類
value
を使用しました。この種類のイベントは、データがほんの 1 か所変更されただけでも、Firebase
データベース参照のコンテンツ全体を読み取ります。
つまり、何かを追加すると、Firebase
データベース参照のコンテンツ全体を読み取り、表示される。
結果、前述の図のような事象が発生する。
コードと解決方法
created: function() { // firebaseからデータを取得する(初回) firebase.database().ref(this.user.uid).once("child_added", (snapshot) =>{ snapshot.forEach((childSnapshot) =>{ let childData = childSnapshot.val(); console.log(childData) this.details.push(childData); }) }) // firebaseからデータを取得する(初回以降) firebase.database().ref(this.user.uid).orderByValue().startAt(this.chekTime).on("child_added", (snapshot) =>{ let childData = snapshot.val(); this.details.push(childData); }) },
解説
// firebaseからデータを取得する(初回) firebase.database().ref(this.user.uid).once("value", (snapshot) =>{ snapshot.forEach((childSnapshot) =>{ let childData = childSnapshot.val(); console.log(childData) this.details.push(childData); }) })
まず1つ目の塊はほとんど前回のコードと変更なし、唯一の変更点は.on()
を.once()
に。
ただこれが非常に重要で、.once()
は下記の通り。
once()
メソッドを使用して、このシナリオを簡素化できます。このメソッドは 1 回トリガーされ、その後再びトリガーされることはありません。
つまり、最初の読み込み時のみの記述になる。
次の塊は2回目以降の処理になる。
// firebaseからデータを取得する(初回以降) firebase.database().ref(this.user.uid).orderByValue().startAt(this.checkTime).on("child_added", (snapshot) =>{ let childData = snapshot.val(); this.details.push(childData); })
こちらは.on
で都度都度データを取得する。
ただ前回のコードと違うのは、新規で追加されたデータだけを取得することができる点。
それを可能にしているのが、下記のコード。
.orderByValue().startAt(this.checkTime)
まず.orderByValue()
は下記の通り。
orderByValue()
を使用すると、子がその値で並べ替えられます。並べ替えの条件は、指定した子キーの値の代わりにノードの値が使用されるという点を除いて、orderByChild()
の場合と同じです。
そして.startAt()
は下記の通り。
startAt()
、endAt()
、equalTo()
を使用すると、クエリに対し任意の始点と終点を選択できます。
この絞り込みにより初期化時(this.checkTime
)*1以降に追加された要素に対してトリガーをするよう対象を絞り込むことができた。
*1:checkTime は投稿時にFirebase に保存しておく必要がある。
Firebase の push() で 自動でIDが付与された子要素の取得したい
はじめに
別記事にて記載したが、Firebase
の Realtime Database
にpush()
した場合、自動でIDが付与される。
saite-name-rtdb ├ user-id ├ -謎の文字列 ├ today ├ 0: "HELLO" └ 1: "GOODBYE" ├ -謎の文字列 ├ today ├ 0: "HELLO" └ 1: "GOODBYE"
こんな感じでJSON
が生成される。
謎の文字列は都度都度、変更するので法則性がない。
そこで、JSON
の子要素を取得するときに困った。
子要素の取得方法
コード
created: function() { firebase.database().ref(this.user.uid).once("value", (snapshot) =>{ snapshot.forEach((childSnapshot) =>{ let childData = childSnapshot.val(); console.log(childData) }) });