Help us understand the problem. What is going on with this article?

Vue.js+Vuex+VuexFireでTodoList

More than 1 year has passed since last update.

最近、Firebaseを勉強中です。Vuexも勉強中です。
その2つをつなぐためのVuexFireというライブラリを組み込んで、TodoListを作ってみました。

とりあえず現状だと接続先のFirebaseデータベース残してるから動くけど、その内消すかも。

コード比較

VuexFireの有無でのStoreのコードを比較してみます。

VuexFireなし
import Vuex from 'vuex';
import Vue from 'vue';
import { ADD_TODO, REMOVE_TODO } from './action-types';

Vue.use(Vuex);

export default new Vuex.Store({
  strict: process.env.NODE_ENV !== 'production',
  state: {
    todos: [],
  },
  mutations: {
    [ADD_TODO](state, text) {
      const todo = {
        id: 0,
        text,
      };
      if (this.state.todos.length !== 0) {
        todo.id = this.state.todos[this.state.todos.length - 1].id + 1;
      }
      this.state.todos.push(todo);
    },
    [REMOVE_TODO](state, id) {
      this.state.todos = this.state.todos.filter(todo => id !== todo.id);
    },
  },
  actions: {
    [ADD_TODO](context, text) {
      context.commit(ADD_TODO, text);
    },
    [REMOVE_TODO](context, id) {
      context.commit(REMOVE_TODO, id);
    },
  },
  getters: {
    getTodos: state => state.todos,
  },
});
VuexFireあり
import Vuex from 'vuex';
import Vue from 'vue';
import * as firebase from 'firebase';
import { firebaseMutations, firebaseAction } from 'vuexfire';
import { ADD_TODO, REMOVE_TODO } from './action-types';

const config = {
  databaseURL: 'https://vue-fire-test-3c227.firebaseio.com/',
};
const firebaseApp = firebase.initializeApp(config);
const db = firebaseApp.database();
const todosRef = db.ref('todo');

Vue.use(Vuex);

const INIT_TODO = 'INIT_TODO';
const myPlugin = store => store.dispatch(INIT_TODO, 'test');

export default new Vuex.Store({
  strict: process.env.NODE_ENV !== 'production',
  state: {
    todos: [],
  },
  mutations: {
    ...firebaseMutations,
  },
  actions: {
    [INIT_TODO]: firebaseAction(({ bindFirebaseRef }) => {
      bindFirebaseRef('todos', todosRef, { wait: true });
    }),
    [ADD_TODO]: firebaseAction((context, text) => {
      todosRef.push(text);
    }),
    [REMOVE_TODO]: firebaseAction((context, key) => {
      todosRef.child(key).remove();
    }),
  },
  getters: {
    getTodos: state => state.todos,
  },
  plugins: [myPlugin],
});

Mutation

一番大きな違いはmutationsの処理がほぼ消えたことです。
そもそもTODOのデータ構造でFirebase側でつけられたキーを使うことができるため、idを管理する必要がなくなったというのもあります。
しかし、本当の理由はstateへの変更はActionで呼び出すbindFirebaseRefによるFirebaseとの連携処理に限定されるからです。
その処理は非同期になるため、すべてActionのほうに書くことになります。

Action

ADD_TODOの処理を見てみます。

todosRef.push(text);

todosRefはFirebaseのdb参照でそこに対してpushを行っています。
todosRefが変更されると、(INIT_TODOでbindingを行っているため)VuexFireが自動的に変更の内容がmutations.todosに連携されます。
つまり、Firebaseにデータを連携させるのは普通にfirebaseの機能を使って行い、Firebase側から現在の状態をstateにbindさせるときにVuexFireの機能を使っています。

VuexFireを入れたときVuexはどうなるか?

VuexFireを使ったときのデータの流れの図です。

まず、Vuexだけの時はこんな感じ。
image.png

Getter経由でComponentにアクセスすることやAPIとの接続が省略されているところを公式サイトとちょっと変えています。

VuexFireが入るとこんな感じ。
image.png

いままで、Actionから呼び出してたMutationがVuexFireのほうから呼び出されて、stateの状態が変更される感じです。
あくまでFirebaseと接続されるデータに着目した図なので、Firebaseと接続されないstateがあれば今まで通りのデータフローになります。

VuexFireの役割

上でも少し述べましたが、VuexFireの役割はFirebase側からstateへのバインディングなので、双方向のやり取りをやってくれるわけではないようです。
あくまでFirebaseへの変更はfirebaseの機能を使うということですね。
最初、VuexFireというものがあると聞いて想像していたのは、設定を書けばstateの状態を監視して自動でFirebaseと連携してくれるみたいなものを想像していたのですが、そういう感じではないようです。
ふつうのVueFireだとどうなんだろう。
なんかVuexとの連携の保証がされないみたいな話がどこかにあって、そっちは使ってないけど。

参考

Vue.js(v2.x.)を使ってメモアプリを作ってみた
vuexfire で Firebase と Vuex をサクッと試してみる
Vue.jsとVuexでTodoListを作ってみた

frost_star
まだまだ半人前プログラマー。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした