2020/10/12 訂正
store内で$routeを使用していましたが、
そもそもstoreで使用不可でした😨
申し訳ございません!
動作はするかもしれませんが、
設計としてはお勧めしません💥
JSでの画面操作系は pages/にしないと
規模が大きくなってきたときに
どこに書いてあるか
わからなくなってしまいます😵
login.vueでdispatchしてユーザー情報を取得すると
ページ遷移するように変更しました💃✨✨
前置き

ログイン機能があると
サービスの幅が広がりますよね🌟
でも難しそう😔
そう思っていませんか?💡
それを解決するのがfirebase Auth!
これを使えば簡単に実装できます💕
今回はログインの実装がメインです!
そのため新規アカウント作成画面は作りません。
まずauthに慣れていきましょう🎶
アプリ開発基礎編
追加オプション機能では
アカウント作成などもやっていきます!
使うもの
Firebase Authentication
Vuex(ログイン状態の保持)
Step1: firebase authの準備
まずはfirebaseでプロジェクトを作成し、
ログイン方法の設定をしていきます🍒
プロジェクトの作成方法はこちら
step1-5. アカウントを選択
プロジェクト概要画面まで
ログイン方法を設定を選択
プロジェクトができたら
サイドメニューAuthentication > ログイン方法を設定

メールを選択

メールでのログインを有効にし、保存

usersタブに戻りユーザーを追加

登録できるとユーザー情報が表示されます🌟

Step2: firebaseとの連携
こちらの記事の
Step3、Step4をご覧ください👀
コード
) file
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import firebase from "firebase/app" if (!firebase.apps.length) { firebase.initializeApp({  apiKey: "貼り付け",  authDomain: "貼り付け",  databaseURL: "貼り付け",  projectId: "貼り付け",  storageBucket: "貼り付け",  messagingSenderId: "貼り付け",  appId: "貼り付け",  measurementId: "貼り付け" }) } export default firebase | 
Step3: ログイン機能の実装

公式ガイドのこちらを見てみましょう👀
Get Startedタブから順番に進めてみます🌸
ログインフォームを作って
methodsにこの関数を書けば良いわけですね💡
signInWithEmailAndPassword()
コード
) pages
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | <template>  <div class="page">    <form      class="form"      @submit.prevent    >      <label class="label">        <span class="label">          email        </span>        <input          class="input"          type="text"          v-model="email"        >      </label>      <label class="label">        <span class="label">          password        </span>        <input          class="input"          type="password"          v-model="password"        >      </label>      <button        class="button"        type="submit"        @click="login"      >        Login      </button>    </form>  </div> </template> <script> import firebase from '~/plugins/firebase' export default {  data() {    return {      email: '',      password: ''    }  },  methods : {    login() {      firebase.auth().signInWithEmailAndPassword(this.email, this.password)      .then(user => {        // eslintがある場合は        // 引数にuser追加とeslint-disable-lineの記載        console.log('成功!')// eslint-disable-line      }).catch((error) => {        alert(error)      });    },  } } </script> <style lang="scss">  .Login {    > .form {      > .button {        display: block;      }      > .label {        > .input {          display: block;          border: 1px solid blck;         }      }    }  } </style> | 
Step4: Vuexに移行
今のままだとログインするだけなので
Vuexを使うメリットがないのですが、
ログインしたという状態を
保持するための準備です!
コード
) pages
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <template>  <div class="page">    <form      class="form"      @submit.prevent    >      <label class="label">        <span class="label">          email        </span>        <input          class="input"          type="text"          v-model="email"        >      </label>      <label class="label">        <span class="label">          password        </span>        <input          class="input"          type="password"          v-model="password"        >      </label>      <button        class="button"        type="submit"        @click="login"      >        Login      </button>    </form>  </div> </template> <script> import firebase from '~/plugins/firebase' export default {  data () {    return {      email: '',      password: '',    }  },  methods : {    login (email, password) {      this.$store.dispatch('login', {email: this.email, password: this.password})    },  } } </script> | 
) file
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import firebase from '~/plugins/firebase' export const state = () => ({ }) export const getters = { } export const actions = {  login(context, payload) {    firebase.auth().signInWithEmailAndPassword(payload.email, payload.password)      .then(user => {          console.log('成功!')        }).catch((error) => {          alert(error)        })  }, } export const mutations = { } | 
解説
index.vueで入力した
email, passwordを引数で渡します🎁
index.jsのactionsでは
第一引数が必ずcontextになるので
第二引数としてemail, passwordを受け取ります📩
Step5: ユーザーデータの取得

ログインができたら
ユーザー情報を表示したいので
情報を取得してきましょう!📩
こちらを見てみましょう👀
onAuthStateChanged()
Set an authentication state observer and get user data
コード
) file
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import firebase from '~/plugins/firebase' export const state = () => ({  user: {    uid: '',    email: '',  }, }) export const getters = {  user: state => {    return state.user  } } export const actions = {  login({ commit }, payload) {    firebase.auth().signInWithEmailAndPassword(payload.email, payload.password)      .then(user => {          console.log('成功!')          firebase.auth().onAuthStateChanged(function (user) {            if (user) {              commit('getData', { uid: user.uid, email: user.email })            }          })        }).catch((error) => {          alert(error)        })  }, } export const mutations = {  getData (state, payload) {    state.user.uid = payload.uid    state.user.email = payload.email  } } | 
解説
それぞれの役割を確認したい方はこちら
【Nuxt.js】Vuexまとめ編:はじめる前に、簡単理解!
state
取得情報の格納場所
getters
stateを取得
actions
- ログイン成功時(.then)に記載
 (ログインと同時に取得)
 step7でログインと取得で
 切り分けるように調整をします✂︎
- ガイド参考
 これで取得ができます!
 ID:user.uid
 💌:user.email
 引数に直接user.uidとは書けないので
 一旦uidと置き換えます
- commit
 ログイン情報をstateに入れるため
 mutationsを呼び出します
mutations
取得した情報でstateを書き換えます
index.vue
computed users()で
gettersを呼び出し表示させておきます
Step6: ログイン情報保持

先ほどログインが成功した時に
ユーザーデータを取得できたので
こちらを追加しましょう!
- stateにログイン状態の真偽値を追加
 ログインできたらtrueに変更
 分かりやすく新たなstateを追加してますが
 ログインできたらstateのuserに
 ユーザー情報をそのまま代入しても
 もちろんOKです!!⭕️
- v-ifで真偽値による出し分け
 ログインtrue, ログアウトfalse
コード
) file
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import firebase from '~/plugins/firebase' export const state = () => ({  user: {    uid: '',    email: '',   // ログイン状態の真偽値を追加    login: false,  }, }) export const getters = {  user: state => {    return state.user  } } export const actions = {  login({ commit }, payload) {    firebase.auth().signInWithEmailAndPassword(payload.email, payload.password)      .then(user => {          console.log('成功!')          firebase.auth().onAuthStateChanged(function (user) {            if (user) {              commit('getData', { uid: user.uid, email: user.email })              // ユーザー情報の取得と同時にcommitで真偽値の切り替え              commit('switchLogin')            }          })        }).catch((error) => {          alert(error)        })  }, } export const mutations = {  getData (state, payload) {    state.user.uid = payload.uid    state.user.email = payload.email  },  // 真偽値を切り替えるmutationsを追加  switchLogin (state) {    state.user.login = true  }, } | 
) pages
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <template>  <div class="page">    <p      v-if="user.login"      class="text"    >      {{ user }}    </p>    <form     v-else    >     // 省略    </form>  </div> </template> <script> import firebase from '~/plugins/firebase' export default {  computed: {    user () {      return this.$store.getters['user']    },  },  data () {    return {      email: '',      password: '',    }  },  methods : {    login (email, password) {      this.$store.dispatch('login', {email: this.email, password: this.password})    },  } } </script> | 
Step7: 調整
login.vueを作成し、
ログインページと
ログイン後のページを分けます。
store/index.jsのactionsを
役割で切り分けてみます✂︎
コード
) pages
index.vueをまるまるコピペ
fibaseのimportが不要→削除
全体のdiv class="login"に変更
また、ログインしたらindex.vueに遷移するよう
$router.pushを追加しています✍️
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | <template>  <div class="login">    <p      v-if="user.login"      class="text"    >      {{ user }}    </p>    <form      v-else      class="form"      @submit.prevent    >      <label class="label">        <span class="label">          email        </span>        <input          class="input"          type="text"          v-model="email"        >      </label>      <label class="label">        <span class="label">          password        </span>        <input          class="input"          type="password"          v-model="password"        >      </label>      <button        class="button"        type="submit"        @click="login"      >        Login      </button>    </form>  </div> </template> <script> export default {  computed: {    user () {      return this.$store.getters['user']    },  },  data () {    return {      email: '',      password: '',    }  },  methods : {    login (email, password) {      this.$store.dispatch('login', {email: this.email, password: this.password})      if (this.$store.getters['user']) {        this.$router.push('/')      }    },  }, } </script> | 
methodsのloginは分かりやすく付け足しましたが
1番スマートな書き方はこちらです❤️
| 1 2 3 4 5 6 7 |  methods : {    login (email, password) {      if (this.$store.dispatch('login', {email: this.email, password: this.password})) // 成功したら1以上がreturnで帰ってくる        this.$router.push('/')      }    },  }, | 
) pages
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <template>  <div class="page">    <p      v-if="user.login"      class="text"    >      ログインに成功!    </p>  </div> </template> <script> export default {  computed: {    user () {      return this.$store.getters['user']    },  }, } </script> | 
) file
2つに切り分けました✂
︎ログイン(login)
ログイン情報の取得(checkLogin)
actions内で別のactionsを
dispatchで呼び出せます📣
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import firebase from '~/plugins/firebase' export const state = () => ({  user: {    uid: '',    email: '',    login: false,  }, }) export const getters = {  user: state => {    return state.user  } } export const actions = {  login({ dispatch }, payload) {    firebase.auth().signInWithEmailAndPassword(payload.email, payload.password)      .then(user => {          console.log('成功!')          dispatch('checkLogin')        }).catch((error) => {          alert(error)        })  },  checkLogin ({ commit }) {    firebase.auth().onAuthStateChanged(function (user) {      if (user) {        commit('getData', { uid: user.uid, email: user.email })        commit('switchLogin')      }    })  }, } export const mutations = {  getData (state, payload) {    state.user.uid = payload.uid    state.user.email = payload.email  },  switchLogin (state) {    state.user.login = true  }, } | 
