|
1 | 1 | # vue-apollo-smart-ops |
2 | 2 |
|
3 | | -Create TypeScript-typed operation functions for your Vue Apollo queries and mutations. |
| 3 | +Creates TypeScript-typed operation functions for GraphQL queries and mutations compatible with |
| 4 | +[Vue Apollo](https://apollo.vuejs.org/). |
| 5 | + |
| 6 | +This library is intended to be used together with the |
| 7 | +[`typescript-vue-apollo-smart-ops` plugin](https://www.graphql-code-generator.com/docs/plugins/typescript-vue-apollo-smart-ops) |
| 8 | +for [GraphQL Code Generator](https://www.graphql-code-generator.com/), but it may also be useful standalone. |
| 9 | + |
| 10 | +## Installation |
| 11 | + |
| 12 | +```shell |
| 13 | +npm install --save vue-apollo-smart-ops |
| 14 | +``` |
| 15 | + |
| 16 | +## Smart Query Usage |
| 17 | + |
| 18 | +### `createSmartQueryOptionsFunction<TResult, TVariables>(query: DocumentNode, onError?: ApolloOperationErrorHandlerFunction): VueApolloSmartQueryOptionsFunction` |
| 19 | + |
| 20 | +Returns a generated function which returns a [Vue Apollo Smart Query options object](https://apollo.vuejs.org/api/smart-query.html#options) |
| 21 | +for the given query when called. |
| 22 | + |
| 23 | +> ⚠️ Note: The returned function is not meant to execute the query itself. It is only used to configure a Vue Apollo |
| 24 | +> Smart Query. The responsibility for executing the query lies with Vue Apollo. |
| 25 | +
|
| 26 | +The returned function accepts an options object as its first argument, allowing variables and other parameters to be |
| 27 | +customised in runtime usage. Compared with creating an options object directly, the advantage here is that the options |
| 28 | +accepted by the generated function are fully type-checked based on the query definition - and without needing to pass |
| 29 | +type arguments at every usage. |
| 30 | + |
| 31 | +Using the [`@graphql-codegen/typescript-vue-apollo-smart-ops` plugin](https://www.graphql-code-generator.com/docs/plugins/typescript-vue-apollo-smart-ops) |
| 32 | +you can automatically generate options functions for all of the query operations in your project. |
| 33 | + |
| 34 | +The following example manually creates an options function and assigns it to the variable `useTodoListQuery`: |
| 35 | + |
| 36 | +```typescript |
| 37 | +const useTodoListQuery = createSmartQueryOptionsFunction<TodosQuery, TodosQueryVariables>(gql` |
| 38 | + query Todos($skip: Int, $limit: Int) { |
| 39 | + todos(skip: $skip, limit: $limit) { |
| 40 | + id |
| 41 | + title |
| 42 | + } |
| 43 | + } |
| 44 | +`); |
| 45 | +``` |
| 46 | + |
| 47 | +This function can subsequently be called inside the `apollo` options of a Vue component to configure a Smart Query. The |
| 48 | +following example adds a `todos` Smart Query to a component, in Vue class component style: |
| 49 | + |
| 50 | +```typescript |
| 51 | +@Component<TodoList>({ |
| 52 | + apollo: { |
| 53 | + todos: useTodoListQuery<TodoList>({ |
| 54 | + skip() { |
| 55 | + return this.foo === 'bar'; |
| 56 | + }, |
| 57 | + variables() { |
| 58 | + return { |
| 59 | + limit: 10, |
| 60 | + skip: 0, |
| 61 | + }; |
| 62 | + }, |
| 63 | + }) |
| 64 | + } |
| 65 | +}) |
| 66 | +class TodoList extends Vue { |
| 67 | + todos: Todo[] | null = null; |
| 68 | + |
| 69 | + get foo(): string { |
| 70 | + return 'bar'; |
| 71 | + } |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +### `@SmartQuery(options: VueApolloSmartQueryOptions)` |
| 76 | + |
| 77 | +The `@SmartQuery()` decorator works with your generated options functions to enable the declaration of Smart Queries |
| 78 | +within the body of a Vue class component, instead of in the component options. This helps to keep the data property and |
| 79 | +its query options together in one place. |
| 80 | + |
| 81 | +The following example is equivalent to the previous example but using the decorated syntax style: |
| 82 | + |
| 83 | +```typescript |
| 84 | +@Component |
| 85 | +class TodoList extends Vue { |
| 86 | + @SmartQuery( |
| 87 | + useTodoListQuery<TodoList>({ |
| 88 | + skip() { |
| 89 | + return this.foo === 'bar'; |
| 90 | + }, |
| 91 | + variables() { |
| 92 | + return this.vars; |
| 93 | + }, |
| 94 | + }), |
| 95 | + ) |
| 96 | + todos: Todo[] | null = null; |
| 97 | + |
| 98 | + get foo(): string { |
| 99 | + return 'bar'; |
| 100 | + } |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +## Mutations Usage |
| 105 | + |
| 106 | +### `createMutationFunction(mutation: DocumentNode, onError?: ): MutationOperationFunction` |
| 107 | + |
| 108 | +Returns a generated function which executes a mutation and returns the result when called. |
| 109 | + |
| 110 | +The returned function requires a Vue app instance as its first argument (from which the `$apollo` client will be |
| 111 | +accessed), and accepts an options object as its second argument, allowing variables and other parameters to be |
| 112 | +customised in runtime usage. Compared with executing a mutation using the Vue Apollo client directly, the advantage here |
| 113 | +is that the options accepted by the generated function are fully type-checked based on the operation definition - and |
| 114 | +without needing to pass type arguments at every usage. |
| 115 | + |
| 116 | +Using the [`@graphql-codegen/typescript-vue-apollo-smart-ops` plugin](https://www.graphql-code-generator.com/docs/plugins/typescript-vue-apollo-smart-ops) |
| 117 | +you can automatically generate mutation functions for all of the mutation operations in your project. |
| 118 | + |
| 119 | +The following example manually creates a mutation function and assigns it to the variable `todoCreateMutation`: |
| 120 | + |
| 121 | +```typescript |
| 122 | +const todoCreateMutation = createMutationFunction<TodoCreateMutation, TodoCreateMutationVariables>(gql` |
| 123 | + mutation TodoCreate($input: TodoInput!) { |
| 124 | + todoCreate(input: $input) { |
| 125 | + todo { |
| 126 | + id |
| 127 | + title |
| 128 | + } |
| 129 | + } |
| 130 | + } |
| 131 | +`); |
| 132 | +``` |
| 133 | + |
| 134 | +The following example demonstrates how to call this mutation from a method on a component: |
| 135 | + |
| 136 | +```typescript |
| 137 | +@Component |
| 138 | +class TodoList extends Vue { |
| 139 | + async onClickCreateTodoButton(): Promise<void> { |
| 140 | + const result = await todoCreateMutation(this, { |
| 141 | + variables: { |
| 142 | + title: 'Bake a cake', |
| 143 | + }, |
| 144 | + }); |
| 145 | + |
| 146 | + if (!result.success) { |
| 147 | + throw new Error(`Failed to create Todo!`); |
| 148 | + } |
| 149 | + } |
| 150 | +} |
| 151 | +``` |
0 commit comments