@Akryum
github.com/Akryum
Apollo
GraphQL
Vue
meteor.io
apollodata.com/optics
Query
Mutation
Subscription (Web socket)
.gql
Observable
query
Normalized Cache
import { ApolloClient, createNetworkInterface }
from 'apollo-client'
// Create the apollo client
const apolloClient = new ApolloClient({
networkInterface: createNetworkInterface({
uri: 'http://localhost:3000/graphql',
}),
connectToDevTools: true,
})
npm i -S apollo-client vue-apollo
yarn add apollo-client vue-apollo
import Vue from 'vue'
import VueApollo from 'vue-apollo'
// Install the vue plugin
Vue.use(VueApollo)
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})
// Add it to the root instance
new Vue({
el: '#app',
apolloProvider,
render: h => h(App),
})
<template>
<nav>
<a v-for="post of posts">{{post.title}}</a>
</nav>
</template>
<script>
export default {
}
</script>
import gql from 'graphql-tag'
const POSTS_QUERY = gql`
query Posts {
posts {
title
}
}
`
export default {
data () {
return {
posts: [],
}
},
// Apollo-specific options
apollo: {
posts: POSTS_QUERY,
},
}
export default {
rules: [
// ...
{
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
loader: 'graphql-tag/loader',
},
]
}
import POSTS_QUERY from '../graphql/Posts.gql'
export default {
// ...
apollo: {
posts: POSTS_QUERY,
},
}
query Post ($id: ID!) {
post (id: $id) {
title
contents
publishedDate
tags
author {
name
company
}
}
}
export default {
props: ['id'],
data () {
return {
post: null,
loading: 0,
}
},
apollo: { /* ... */ },
}
apollo: {
post: {
query: POST_QUERY,
variables () {
return { id: this.id }
},
loadingKey: 'loading',
},
},
Helping you
consume Reactive Data
Efficiently
Reactive
Data
Component
Created /
Activated
consumers++
consumers > 0
Now Active
Supply
Subscribe
Reactive
Data
Component
Destroyed /
Deactivated
consumers--
consumers === 0
Now Inactive
Supply
Unsubscribe
npm i -S vue-supply
yarn add vue-supply
import Vue from 'vue'
import VueSupply from 'vue-supply'
Vue.use(VueSupply)
import { Supply } from 'vue-supply'
import apolloProvider from '../apollo-provider'
export default {
extends: Supply,
apolloProvider,
apollo: {
$skipAll () {
return !this.active
},
},
}
import Base from './BaseApolloSupply.js'
export default {
extends: Base,
data () {
return { posts: [] },
},
apollo: {
posts: {
query: POSTS_QUERY,
loadingKey: 'loading',
},
},
}
apollo: {
posts: {
query: POSTS_QUERY,
subscribeToMore: {
document: POST_ADDED_QUERY,
updateQuery (previousResult, { sub }) {
return {
posts: [
...previousResult.posts,
sub.data.newPost,
],
}
import { register } from 'vue-supply'
import Posts from './PostsSupply.js'
register('Posts', Posts)
import { use } from 'vue-supply'
export default {
// This component now uses Posts supply
mixins: [use('Posts')],
// Use the values in computed properties
computed: {
filteredPosts () {
return this.$supply.Posts.posts.filter(...)
},
},
}
<template>
<section>
<div v-if="!$supply.Posts.ready">
Loading...
</div>
<div v-for="tag of $supply.Posts.posts">
{{ post.title }}
</div>
</section>
</template>
export default {
supply: {
use: ['Posts'],
inject: ({ Posts }) => ({
getters: {
'all-posts': () => Posts.items,
},
}),
},
getters: {
'posts-count': (state, getters) => {
return getters['all-posts'].length
},
},
}
import { injectSupply } from 'vue-supply'
import storeOptions from './vuex/store.js'
// Prevent duplicate supplies!
const supplyCache = {}
const o = injectSupply(storeOptions, supplyCache)
const store = new Vuex.Store(o)
new Vue({
// ...
store,
supplyCache,
}),
import { use } from 'vue-supply'
import { mapGetters } from 'vuex'
export default {
// This component now uses Posts supply
mixins: [use('Posts')],
// Getter that uses the supply
computed: mapGetters({
items: 'all-posts',
}),
}
supply: {
use: ['Posts'],
inject: ({ Posts }) => ({
actions: {
'subscribe-action' () {
Posts.grasp()
return Posts.ensureReady()
},
'unsubscribe-action' () {
Posts.release()
},
}
}),
}
export default {
actions: {
async foo ({ dispatch, getters }) {
await dispatch('subscribe-action')
const data = getters['all-posts']
dispatch('unsubscribe-action')
},
},
}
@Akryum
github.com/Akryum