こんな感じになります
追記2018/12/13
Nuxt.js版ライブデモ on Netlifyを稼働。
ポイント
- vuexは使わない
- 代わり、apollo-link-stateと、vueからapolloを使いやすくするvue-apolloを使う
-
withClientState
を使ってLinkを作る-
defaults
にフィールドcountSample
、最初の値0
を入れる -
resolvers
にカウンタの値を増加させるmutation
を作る
-
- コンポーネントからは
$
のついていないapollo
というフィールドで、どの変数に値を入れるかを設定する-
mutation
をthis.$apollo.mutate
で呼び出す
-
Linkを作る
-
stateLink
という、普通のGraphQLのlinkとは違うLinkを作成します
main.ts
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import VueApollo from 'vue-apollo'
import { withClientState } from 'apollo-link-state';
import { readCache, writeCache } from './apollo-link-state-store'
Vue.use(VueApollo)
const stateLink = withClientState({
cache: new InMemoryCache(),
defaults: {
countSample: 0
},
resolvers: {
Mutation: {
increment: (obj: any, args: any, {cache}: any) => {
var rtn = readCache(cache, "countSample")
writeCache(cache, "countSample", rtn + 1)
return null
},
},
},
});
const apolloProvider = new VueApollo({
defaultClient: new ApolloClient({
link: stateLink,
cache: new InMemoryCache(),
connectToDevTools: true
})
})
new Vue({
router,
store,
apolloProvider,
render: (h) => h(App),
}).$mount('#app');
こうして関数化しておくと楽(GraphQLお作法の隠蔽)
-
apollo-link-state
は癖が強いので、自分で簡単関数apollo-link-state-store
を作りました。
apollo-link-state-store.ts
import gql from 'graphql-tag'
const argRead = (key: string) => gql`{ ${key} @client}`
const argReadCache = (key: string) => {
return { query: argRead(key)}
}
const argWriteCache = (key:string, value: any) => {
return {data: { [key]: value }}
}
//これをmain.tsから呼ぶ
export const readCache = (cache: any, key:string) => {
return cache.readQuery(argReadCache(key))[key]
}
//これをmain.tsから呼ぶ
export const writeCache = (cache: any, key: string, value: any) => {
return cache.writeData(argWriteCache(key, value))
}
//これをコンポーネントから呼ぶ
export const argMutate = (mutation: string) => {
return {
mutation: gql`mutation { ${mutation} @client }`
}
}
//これをコンポーネントから呼ぶ
export const apolloState = (key: string) => {
return {
query: argRead(key),
loadingKey: 'loading'
}
}
そしてコンポーネントからはこう呼ぶ
<template>
<div>
<div> {{ countSample }} </div>
<v-btn color="success" v-on:click="increment()" > +1 </v-btn>
</div>
</template>
<script>
import { apolloState, argMutate } from '../apollo-link-state-store'
export default {
apollo: {
countSample: apolloState("countSample")
},
data () {
return {
countSample: 0
}
},
methods: {
increment() {
this.$apollo.mutate(argMutate("increment"))
}
},
}
</script>
まとめ
- 癖が強いapollo-link-stateの作法を、半分くらい関数化して隠蔽する
apollo-link-state-store.ts
を作った。 - Vuexなくてもストアは作れる
- ただ、それが本当に嬉しいのかは人によるかな
- apollo-link-stateを使うことで、reduxやvuexに縛られない、フレームワークをまたぐようなストアもできそうな気がする。そういうのってマイクロフロントエンドとして必要にならないだろうか。FiNCなどの先人を切っている方がそういうストアをどうしているのかが気になる。
おまけ
- Nuxt.jsで簡単なサンプルプログラム作成
- 今回のapollo-link-stateカウンターを移植
ができました。
ソースコードはこちら。
そしてNetlify上のライブデモです。
ご査収ください