Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(useAxios): axios instance support, close #273 #342

Merged
merged 2 commits into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/integrations/useAxios/demo.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup lang="ts">
import { stringify } from '@vueuse/docs-utils'
import { defineComponent } from 'vue-demi'
import { useAxios } from '.'

const { data, finished } = useAxios(
Expand Down
25 changes: 25 additions & 0 deletions packages/integrations/useAxios/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,31 @@ import { useAxios } from '@vueuse/integrations'
const { data, finished } = useAxios('/api/posts')
```

or use an instance of axios

```ts
import axios from 'axios'
import { useAxios } from '@vueuse/integrations'

const instance = axios.create({
baseUrl: '/api'
})

const { data, finished } = useAxios('/posts', instance)
```

use an instance of axios with config options

```ts
import axios from 'axios'
import { useAxios } from '@vueuse/integrations'

const instance = axios.create({
baseUrl: '/api'
})

const { data, finished } = useAxios('/posts', { method: 'POST' }, instance)
```

<!--FOOTER_STARTS-->
## Type Declarations
Expand Down
36 changes: 30 additions & 6 deletions packages/integrations/useAxios/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import { Ref, ref } from 'vue-demi'
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, CancelTokenSource } from 'axios'
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, CancelTokenSource, AxiosInstance } from 'axios'

interface UseAxiosReturn<T> {
response: Ref<AxiosResponse<T> | undefined>
data: Ref<T | undefined>
finished: Ref<boolean>
canceled: Ref<boolean>
error: Ref<AxiosError<T> | undefined>
}

export function useAxios<T = any>(url: string, config?: AxiosRequestConfig): UseAxiosReturn<T>
export function useAxios<T = any>(url: string, instance?: AxiosInstance): UseAxiosReturn<T>
export function useAxios<T = any>(url: string, config: AxiosRequestConfig, instance: AxiosInstance): UseAxiosReturn<T>

/**
* Wrapper for axios.
Expand All @@ -8,10 +20,22 @@ import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, CancelTokenSource
* @param url
* @param config
*/
export function useAxios<T = any>(
url: string,
config?: AxiosRequestConfig,
) {
export function useAxios<T = any>(url: string, ...args: any[]) {
let config: AxiosRequestConfig = {}
let instance: AxiosInstance = axios

if (args.length > 0) {
if ('request' in args[0])
Copy link
Member

@antfu antfu Feb 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a safe way to detect whether it's an axios instance?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to use instanceof but it looks like you can't do that(axios/axios#737) so I used the way that was suggested here. It doesn't seem to have any overlap with the AxiosRequestConfig, so it works from my testing. But I guess the only real way to enforce it is with the typescript types for parameters. If you have any ideas on another way to do it let me know.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, go with it then. Can you add a comment above that line mentioning about the issue you linked? Thanks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing!

instance = args[0]
else
config = args[0]
}

if (args.length > 1) {
if ('request' in args[1])
instance = args[1]
}

const response = ref<any>(null) as Ref<AxiosResponse<T> | undefined>
const data = ref<any>(undefined) as Ref<T | undefined>
const finished = ref(false)
Expand All @@ -24,7 +48,7 @@ export function useAxios<T = any>(
canceled.value = true
}

axios(url, { ...config, cancelToken: cancelToken.token })
instance(url, { ...config, cancelToken: cancelToken.token })
.then((r: AxiosResponse<T>) => {
response.value = r
data.value = r.data
Expand Down