File tree Expand file tree Collapse file tree 10 files changed +205
-27
lines changed
vue-apollo-composable/src Expand file tree Collapse file tree 10 files changed +205
-27
lines changed Original file line number Diff line number Diff line change 20
20
"@vue/apollo-util" : " workspace:*" ,
21
21
"graphql" : " ^16.7.1" ,
22
22
"graphql-tag" : " ^2.12.6" ,
23
+ "pinia" : " ^2.1.6" ,
23
24
"test-server" : " workspace:*" ,
24
25
"vue" : " ^3.3.4" ,
25
26
"vue-router" : " ^4.2.4"
Original file line number Diff line number Diff line change
1
+ <script lang="ts" setup>
2
+ import { computed } from ' vue'
3
+ import ChannelList from ' ./ChannelList.vue'
4
+ import GlobalLoading from ' ./GlobalLoading.vue'
5
+ import { useRoute } from ' vue-router'
6
+
7
+ const route = useRoute ()
8
+
9
+ const displayChannels = computed (() => ! route .matched .some (r => r .meta ?.layout === ' blank' ))
10
+ </script >
11
+
1
12
<template >
2
13
<GlobalLoading />
3
14
<div class =" flex h-screen items-stretch bg-gray-100" >
4
- <ChannelList class =" w-1/4 border-r border-gray-200" />
15
+ <ChannelList
16
+ v-if =" displayChannels"
17
+ class =" w-1/4 border-r border-gray-200"
18
+ />
5
19
<router-view class =" flex-1 overflow-auto" />
6
20
</div >
7
21
</template >
8
-
9
- <script lang="ts">
10
- import { defineComponent } from ' vue'
11
- import ChannelList from ' ./ChannelList.vue'
12
- import GlobalLoading from ' ./GlobalLoading.vue'
13
-
14
- export default defineComponent ({
15
- name: ' App' ,
16
-
17
- components: {
18
- ChannelList ,
19
- GlobalLoading ,
20
- },
21
- })
22
- </script >
Original file line number Diff line number Diff line change
1
+ <script lang="ts" setup>
2
+ import { useChannels } from ' @/stores/channel'
3
+
4
+ const channelStore = useChannels ()
5
+ </script >
6
+
7
+ <template >
8
+ <div
9
+ v-if =" channelStore.loading"
10
+ class =" p-12 text-gray-500"
11
+ >
12
+ Loading channels...
13
+ </div >
14
+
15
+ <div
16
+ v-else
17
+ class =" flex flex-col bg-white"
18
+ >
19
+ <router-link
20
+ v-for =" channel of channelStore.channels"
21
+ :key =" channel.id"
22
+ v-slot =" { href, navigate, isActive }"
23
+ :to =" {
24
+ name: 'channel',
25
+ params: {
26
+ id: channel.id,
27
+ },
28
+ }"
29
+ custom
30
+ >
31
+ <a
32
+ :href =" href"
33
+ class =" channel-link px-4 py-2 hover:bg-green-100 text-green-700"
34
+ :class =" {
35
+ 'bg-green-200 hover:bg-green-300 text-green-900': isActive,
36
+ }"
37
+ @click =" navigate"
38
+ >
39
+ # {{ channel.label }}
40
+ </a >
41
+ </router-link >
42
+ </div >
43
+ </template >
Original file line number Diff line number Diff line change
1
+ <script lang="ts" setup>
2
+ import { useChannels } from ' @/stores/channel'
3
+ import { onBeforeUnmount , ref , watch } from ' vue'
4
+
5
+ const channels = ref <any []>([])
6
+
7
+ let unwatch: (() => void ) | undefined
8
+ setTimeout (() => {
9
+ const channelStore = useChannels ()
10
+ unwatch = watch (() => channelStore .channels , (newChannels ) => {
11
+ channels .value = newChannels
12
+ }, {
13
+ immediate: true ,
14
+ })
15
+ }, 0 )
16
+
17
+ onBeforeUnmount (() => {
18
+ unwatch ?.()
19
+ })
20
+ </script >
21
+
22
+ <template >
23
+ <div
24
+ v-if =" channels"
25
+ class =" flex flex-col bg-white"
26
+ >
27
+ <router-link
28
+ v-for =" channel of channels"
29
+ :key =" channel.id"
30
+ v-slot =" { href, navigate, isActive }"
31
+ :to =" {
32
+ name: 'channel',
33
+ params: {
34
+ id: channel.id,
35
+ },
36
+ }"
37
+ custom
38
+ >
39
+ <a
40
+ :href =" href"
41
+ class =" channel-link px-4 py-2 hover:bg-green-100 text-green-700"
42
+ :class =" {
43
+ 'bg-green-200 hover:bg-green-300 text-green-900': isActive,
44
+ }"
45
+ @click =" navigate"
46
+ >
47
+ # {{ channel.label }}
48
+ </a >
49
+ </router-link >
50
+ </div >
51
+ </template >
Original file line number Diff line number Diff line change 1
- import { createApp , h , provide } from 'vue'
1
+ import { createApp } from 'vue'
2
2
import { DefaultApolloClient } from '@vue/apollo-composable'
3
+ import { createPinia } from 'pinia'
3
4
import { apolloClient } from './apollo'
4
5
import App from './components/App.vue'
5
6
import { router } from './router'
6
7
import '@/assets/styles/tailwind.css'
7
8
8
- const app = createApp ( {
9
- setup ( ) {
10
- provide ( DefaultApolloClient , apolloClient )
11
- } ,
12
- render : ( ) => h ( App ) ,
13
- } )
9
+ const app = createApp ( App )
10
+ app . use ( createPinia ( ) )
14
11
app . use ( router )
12
+ app . provide ( DefaultApolloClient , apolloClient )
15
13
app . mount ( '#app' )
Original file line number Diff line number Diff line change @@ -50,5 +50,19 @@ export const router = createRouter({
50
50
path : '/null-query' ,
51
51
component : ( ) => import ( './components/NullQuery.vue' ) ,
52
52
} ,
53
+ {
54
+ path : '/pinia' ,
55
+ component : ( ) => import ( './components/ChannelListPinia.vue' ) ,
56
+ meta : {
57
+ layout : 'blank' ,
58
+ } ,
59
+ } ,
60
+ {
61
+ path : '/pinia2' ,
62
+ component : ( ) => import ( './components/ChannelListPinia2.vue' ) ,
63
+ meta : {
64
+ layout : 'blank' ,
65
+ } ,
66
+ } ,
53
67
] ,
54
68
} )
Original file line number Diff line number Diff line change
1
+ import gql from 'graphql-tag'
2
+ import { useQuery } from '@vue/apollo-composable'
3
+ import { defineStore } from 'pinia'
4
+ import { computed , watch } from 'vue'
5
+
6
+ interface Channel {
7
+ id : string
8
+ label : string
9
+ }
10
+
11
+ export const useChannels = defineStore ( 'channel' , ( ) => {
12
+ const query = useQuery < { channels : Channel [ ] } > ( gql `
13
+ query channels {
14
+ channels {
15
+ id
16
+ label
17
+ }
18
+ }
19
+ ` )
20
+
21
+ const channels = computed ( ( ) => query . result . value ?. channels ?? [ ] )
22
+
23
+ watch ( query . loading , value => {
24
+ console . log ( 'loading' , value )
25
+ } , {
26
+ immediate : true ,
27
+ } )
28
+
29
+ return {
30
+ loading : query . loading ,
31
+ channels,
32
+ }
33
+ } )
Original file line number Diff line number Diff line change
1
+ describe ( 'Pinia' , ( ) => {
2
+ beforeEach ( ( ) => {
3
+ cy . task ( 'db:reset' )
4
+ } )
5
+
6
+ it ( 'with current instance' , ( ) => {
7
+ cy . visit ( '/pinia' )
8
+ cy . get ( '.channel-link' ) . should ( 'have.lengthOf' , 2 )
9
+ cy . contains ( '.channel-link' , '# General' )
10
+ cy . contains ( '.channel-link' , '# Random' )
11
+ } )
12
+
13
+ it ( 'with effect scope only' , ( ) => {
14
+ cy . visit ( '/pinia2' )
15
+ cy . get ( '.channel-link' ) . should ( 'have.lengthOf' , 2 )
16
+ cy . contains ( '.channel-link' , '# General' )
17
+ cy . contains ( '.channel-link' , '# Random' )
18
+ } )
19
+ } )
Original file line number Diff line number Diff line change 1
- import { getCurrentInstance , inject } from 'vue-demi'
1
+ import { getCurrentInstance , getCurrentScope , inject } from 'vue-demi'
2
2
import { ApolloClient } from '@apollo/client/core/index.js'
3
3
4
4
export const DefaultApolloClient = Symbol ( 'default-apollo-client' )
@@ -35,7 +35,7 @@ export function useApolloClient<TCacheShape = any> (clientId?: ClientId): UseApo
35
35
// Save current client in current closure scope
36
36
const savedCurrentClients = currentApolloClients
37
37
38
- if ( ! getCurrentInstance ( ) ) {
38
+ if ( ! getCurrentInstance ( ) && ! getCurrentScope ( ) ) {
39
39
resolveImpl = ( id ?: ClientId ) => {
40
40
if ( id ) {
41
41
return resolveClientWithId ( savedCurrentClients , id )
@@ -68,7 +68,7 @@ export function useApolloClient<TCacheShape = any> (clientId?: ClientId): UseApo
68
68
throw new Error (
69
69
`Apollo client with id ${
70
70
id ?? 'default'
71
- } not found. Use provideApolloClient() if you are outside of a component setup.`,
71
+ } not found. Use an app.runWithContext() or provideApolloClient() if you are outside of a component setup.`,
72
72
)
73
73
}
74
74
return client
You can’t perform that action at this time.
0 commit comments