如何用vue3+ts,写一个异步请求的hooks

·  阅读 2526
如何用vue3+ts,写一个异步请求的hooks

描述

我们在业务中,经常要异步请求数据,来渲染我们的页面,而且为了代码和逻辑的复用,我们可以封装成一个hooks

技术栈

  • vue3
  • typescript
import { toRefs, reactive, onMounted } from 'vue'

type Service<R = any, P extends any[] = any[]> = (...args: P) => Promise<R>

type OptionsType = {
  /** 是否手动调用 */
  manual?: boolean
  /** 初始化数据 */
  initialData?: any
  /** 成功回调 */
  onSuccess?: () => void
  /** 失败回调 */
  onError?: (e: Error | null) => void
  /** 其他属性 */
  [propName: string]: any
}

type StateType<D> = {
  data: D
  loading: boolean
  error: Error | null
}

/**
 * useAsync
 * @param  {Promise} pro 异步操作
 * @param  {Object} options 参数
 * @param  {Boolean} [options.manual=false] 是否手动调用
 * @param  {Any} options.initialData 初始化数据
 * @param  {Function} options.onSuccess 成功回调
 * @param  {Function} options.onError 失败回调
 */

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()
  })

  // 从外部主动改变数据
  function mutate(data: T) {
    state.data = data
  }
  return {
    ...toRefs(state),
    run,
    mutate
  }
}

复制代码

使用

<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>
复制代码

总结

ts版源码地址

js版源码地址

useAsync使用文档

useAsync插件来自ant-simple-pro里面,ant-simple-pro有很多用vue3+ts开发的插件。ant-simple-pro简洁,美观,快速上手,支持3大框架。

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改