Vuex で状態管理

  1. Google App Engine Java Standard + Spring Boot 環境構築
  2. Spring Bootのテンプレートエンジン Thymeleafを適用

  3. Spring BootにVue.jsを利用する

  4. Spring BootにVuetify導入からクロスドメインAjax通信

  5. Spring Boot+Vuetify GAEへデプロイ、動作確認

  6. Xamarin.FormsアプリをiOS用にビルド

  7. Xamarin.Forms ポップアップの表示と Http通信

  8. Spring Boot+Vuetify ファイルのアップロードとJSONで結果を返す

  9. Google Google Cloud Vision でOCR。VuetifyからSpringBoot経由で呼び出し

  10. Xamarin ファイル選択

  11. Xamarin ファイルのアップロード

  12. Vue Router を導入し画面遷移

  13. Firebaseでログイン機能

1.Vuex

Firebase を使用して、ログイン機能を追加できた。

つぎは、コンポーネント間で、データのやり取りを行いたい。

状態管理を行う手法の記述があるが、Fluxライクな公式実装ということで、Vuex を素直に使用する。

https://vuex.vuejs.org/ja/

動画チュートリアル

1.1 インストール

npm install vuex --save

2.実装

2.1 main.js

  • Vue.user(Vuex) で使用準備
  • Vuex.Store でストアを作成
  • state に、firebase のログインユーザー情報を格納
  • muattions で、stateに設定した user情報を操作するメソッドを公開
  • firebase のユーザーが取得出来たら、store.commit にて、stateにユーザーを格納する
  • new Vue() 内に、storeを設定することで、グローバルにstoreを参照できるように

import Vue from 'vue'
import Vuex from 'vuex'
import '@/plugins/vuetify'
import firebase from '@/plugins/firebase'
import 'firebase/auth'

import { MUTATION_LOGIN_USER } from '@/consts'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    user:null
  },
  mutations: {
    user(state, user) {
      state.user = user;
    }
  }
})

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    store.commit(MUTATION_LOGIN_USER, user);
  } 
})

new Vue({
  render: h => h(App),
  store,
}).$mount('#app')

2.2 const.js

ミューテーションを介して、stateを操作するが、ミューテーションを介した操作をトラックするためにミューテーションの名称を外だし

export const MUTATION_LOGIN_USER = "user";

2.3 App.vue

  • computed の userName で、Vuexのstoreから、firebaseのログインユーザを取得する
  • {{userName}} で上記にバインド。ログインユーザーの表示名をツールバーに表示する
<template>
  <v-app>
    <v-navigation-drawer fixed clipped app v-model="navBar">
      <v-list dense class="pt-0">
        <router-link to="/login">
          <v-list-tile>
            <v-list-tile-action>
              <v-avatar v-if="photoUrl" size="28px">
                <img :src="photoUrl">
              </v-avatar>
              <v-icon v-else>account_box</v-icon>
            </v-list-tile-action>
            <v-list-tile-content>{{userName}}</v-list-tile-content>
          </v-list-tile>
        </router-link>
        <router-link to="/">
          <v-list-tile>
            <v-list-tile-action>
              <v-icon>home</v-icon>
            </v-list-tile-action>
            <v-list-tile-content>HOME</v-list-tile-content>
          </v-list-tile>
        </router-link>
        <router-link to="/entry">
          <v-list-tile>
            <v-list-tile-action>
              <v-icon>edit</v-icon>
            </v-list-tile-action>
            <v-list-tile-content>ENTRY</v-list-tile-content>
          </v-list-tile>
        </router-link>
        <router-link to="/about">
          <v-list-tile>
            <v-list-tile-action>
              <v-icon>settings</v-icon>
            </v-list-tile-action>
            <v-list-tile-content>ABOUT</v-list-tile-content>
          </v-list-tile>
        </router-link>
      </v-list>    
    </v-navigation-drawer>
    <v-toolbar clipped-left fixed app>
      <v-toolbar-side-icon @click.stop="navBar = !navBar"></v-toolbar-side-icon>
      <v-toolbar-title>FavoPhrase</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-toolbar-items class="hidden-sm-and-down">
        <v-btn flat to="/">Home</v-btn>
        <v-btn flat to="/entry">Entry</v-btn>
        <v-btn flat to="/about">About</v-btn>
        <v-btn flat to="/login">
           <v-avatar v-if="photoUrl" size="32px" class="pa-4">
              <img :src="photoUrl">
           </v-avatar>
          {{userName}}
        </v-btn>
      </v-toolbar-items>
    </v-toolbar>
    <v-content>
      <v-container fluid fill-height>
        <v-fade-transition mode="out-in">
          <router-view></router-view>
        </v-fade-transition>
      </v-container>
    </v-content>
  </v-app>
</template>

<script>
  import firebase from '@/plugins/firebase'

  export default {
    name: 'App',
    data() {
      return {
        navBar: null,
      }
    },
    computed: {
      userName() {
        var user = this.$store.state.user;
        if (user != null) {
          if (user.displayName) {
            return user.displayName;
          }
          if (user.email) { 
            return user.email;
          }
        }
        return "LOG IN";
      },
      photoUrl() {
        var user = this.$store.state.user;
        return (user == null)?null:user.photoURL;
      }
    },
    created() {
    },
    mounted() {
    }
  }
</script>
<style>
  a {
    text-decoration: none;
  }
</style>

Reduxより使いやすそう

3.実行

3.1 ログインしていない状態から

login

3.2 Firebase ログインUIから、ログイン

firebaseui_login

3.3 ログインが成功し表示名とアイコンが表示された OK

avater