describe
In our business, we often request data asynchronously to render our pages, and for code and logic reuse we can wrap it in hooks
Technology stack
- vue3
- typescript
import { toRefs, reactive, onMounted } from 'vue'
type Service<R = any, P extends any[] = any[] > =(. args: P) = > Promise<R>
type OptionsType = {
/** Whether to call */ manuallymanual? :boolean
/** Initializes data */initialData? :any
/** Successful callback */onSuccess? :() = > void
/** Failed callback */onError? :(e: Error | null) = > void
/** Other attributes */
[propName: string] :any
}
type StateType<D> = {
data: D
loading: boolean
error: Error | null
}
/**
* useAsync
* @param {Promise} Pro asynchronous operation *@param {Object} The options parameter *@param {Boolean} [options.manual=false] Whether to call * manually@param {Any} Options. initialData Initializes data *@param {Function} Options. onSuccess Callback successfully *@param {Function} Options. onError Failed callback */
export function useAsync<T = any> (pro: Service<T>, options: OptionsType = {}) {
const {
manual = false,
initialData,
onSuccess = () = > {}, // eslint-disable-line
onError = console.log
} = options
const state: StateType<T> = reactive({
data: initialData || null.error: null.loading: false
})
const run = async () => {
state.error = null
state.loading = true
try {
const result = await pro()
state.data = result
onSuccess()
} catch (err) {
onError(err)
state.error = err
}
state.loading = false
}
onMounted(() = > {
!manual && run()
})
// Change data actively from the outside
function mutate(data: T) {
state.data = data
}
return {
...toRefs(state),
run,
mutate
}
}
Copy the code
use
<template>
<ul>
<li v-for="(item, index) in list" :key="index">{{item.name}}</li>
</ul>
</template>
<script>
import { defineComponent, ref } from 'vue'
function getUsers() {
return new Promise(resolve= > {
setTimeout(() = > {
resolve([
{ name: 'foo' },
{ name: 'bar' },
{ name: 'baz'}}]),1000)})}export default defineComponent({
setup() {
const { data: list } = useAsync(
() = > {
return getUsers()
},
{
initialData: []})return {
list
}
}
})
</script>
Copy the code
conclusion
Ts version source address
Js version of the source address
UseAsync uses documentation
The useAsync plugin comes from ant-simple-Pro, which has many plugins developed with vue3+ TS. Ant-simple-pro is simple, beautiful and quick to use, supporting 3 big frames.