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 }, } |