Vuex で状態管理
1.Vuex
Firebase を使用して、ログイン機能を追加できた。
つぎは、コンポーネント間で、データのやり取りを行いたい。
状態管理を行う手法の記述があるが、Fluxライクな公式実装ということで、Vuex を素直に使用する。
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>
3.実行
3.1 ログインしていない状態から
3.2 Firebase ログインUIから、ログイン
3.3 ログインが成功し表示名とアイコンが表示された OK
|