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: extend useFetch: add manual trigger option, add data to the return value. #499

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 51 additions & 3 deletions src/runtime/composables/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
ref,
isRef,
onBeforeMount,
onServerPrefetch,
Expand Down Expand Up @@ -49,7 +50,11 @@ function createGetCounter(counterObject: Record<string, any>, defaultKey = '') {
}

interface Fetch {
(context: ComponentInstance): void | Promise<void>
(context: ComponentInstance): any | Promise<any>
}
interface UseFetchOptions {
expose?: string,
manual?: boolean,
}

const fetches = new WeakMap<ComponentInstance, Fetch[]>()
Expand Down Expand Up @@ -266,12 +271,54 @@ function getKey(vm: AugmentedComponentInstance) {
},
})
```

```ts
import { defineComponent, ref, useFetch } from '@nuxtjs/composition-api'
import axios from 'axios'

export default defineComponent({
setup() {
const { fetch, fetchState, data } = useFetch(
async () => {
// The return value will be set to
return await axios.get('https://myapi.com/name')
},
{
manual: true, // Disable auto fetch unless `fetch()` is called manually
expose: 'name', // The name exposed to the template by which can access the hook's return value
},
)

// Manually trigger a refetch
fetch()

// Access the returned value of fetch hook
data.value
},
})
```
*/
export const useFetch = (callback: Fetch) => {
export const useFetch = (callback: Fetch, options: UseFetchOptions) => {
const vm = getCurrentInstance() as AugmentedComponentInstance | undefined
if (!vm) throw new Error('This must be called within a setup function.')

registerCallback(vm, callback)
const resultData = ref()
let callbackProxy: Fetch = async function (this: any, ...args) {
const result = await callback.apply(this, args)
resultData.value = result
return result
}
if (options.manual) {
let callbackManually:Fetch = () => {
callbackManually = callbackProxy
}
registerCallback(vm, callbackManually)
} else {
registerCallback(vm, callbackProxy)
}
if (options.expose) {
vm[options.expose] = resultData
}

if (typeof vm.$options.fetchOnServer === 'function') {
vm._fetchOnServer = vm.$options.fetchOnServer.call(vm) !== false
Expand All @@ -293,6 +340,7 @@ export const useFetch = (callback: Fetch) => {
fetchState: vm!.$fetchState,
$fetch: vm!.$fetch,
$fetchState: vm!.$fetchState,
data: resultData,
}
}

Expand Down