Vuex
Firestore
+
2018-08-03 pixiv社内勉強会
@hakatashi
書き込み
同期
Firestore
Function
複雑なこと
HTTPリクエスト
“VuexFire”が便利
DBの/counter/counterをVuexの$store.state.counterにbindする
import {firebaseAction, firebaseMutations} from 'vuexfire';
const counterRef = db.collection('counter').doc('counter');
export default new Vuex.Store({
state: {
counter: null,
},
mutations: {
...firebaseMutations,
},
actions: {
bindCounter: firebaseAction(async ({bindFirebaseRef}) => {
await bindFirebaseRef('counter', counterRef);
}),
},
});
<template>
<p>Count: {{counter}}</p>
</template>
<script>
export default {
data() {
return { initialized: false };
},
computed: {
...mapGetters(['counter']),
},
mounted() {
this.$store.dispatch('bindCounter').then(() => {
this.initialized = true;
});
},
destroyed() {
this.$store.dispatch('unbindCounter');
},
};
</script>
例えば、Vue Component のmount時にbindして、destroy時にunbindする
export default new Vuex.Store({
state: {
data: {},
},
actions: {
bindById: firebaseAction(async ({bindFirebaseRef, state}, id) => {
// 二重bindを防ぐ
if (state.data[id]) {
return;
}
const couplingRef = couplingsRef.doc(id);
await bindFirebaseRef(`data.${id}`, couplingRef);
}),
},
});
オブジェクトの形でデータを持つ (賛否両論)
Vuexfireには二重bindを防ぐ機構がないので注意が必要
actions: {
bindCharacter: firebaseAction(async ({bindFirebaseRef, dispatch}, {name}) => {
// 二重bindを防ぐ (省略)
const characters = await charactersRef.where('name', '==', name).get();
const character = characters.docs[0];
const characterBindPromise = bindFirebaseRef(`data.${character.id}`, character.ref);
const couplings = await couplingsRef.where(`members.${character.id}`, '==', true).get();
await Promise.all([
characterBindPromise,
...couplings.docs.map((coupling) => (
dispatch('couplings/bind', coupling.id, {root: true})
)),
]);
}),
}
bindと同時にクエリを実行し、全部bindしたらresolveする
UI上でどんどんデータが降ってくる様子が見えるのでエモい (?)
export default {
async fetch({store, params}) {
if (!process.browser) {
await store.dispatch('characters/bindCharacter', {
name: params.name,
});
}
},
...
};
Nuxt.jsならfetchメソッドに突っ込めば一発
ただgenerateのたびにDBにアクセスして重いのでなんとかしたい