vue3 typescript 分页 hook 如何编写?

最近在用 vue3 开发项目,但是我对 typescript 不太熟悉,麻烦各位大佬提供些思路,我快要被这个类型定义搞疯了。。。
下面是我想要抽成 hook 的代码。


const refreshing = ref(false)
const loading = ref(false)
const finished = ref(false)
const pageData = ref<BaseResponsePageInfo>()
const data= ref<IData[]>([])
const queryParams = ref<IQuery>({
  pageNum: 10,
  pageSize: 1
})
// 获取数据
async function fetchData() {
  try {
    loading.value = true
    const { list, ...pageInfo } = await getList(queryParams.value)
    pageData.value = pageInfo
    if (refreshing.value) {
      data.value = list
    } else {
      data.value = data.value.concat(list)
    }
    if (pageInfo.isLastPage) {
      finished.value = true
    }
  } finally {
    loading.value = false
    refreshing.value = true
  }
}
// 刷新
function onRefresh() {
  refreshing.value = true
  console.log('onRefresh');
  fetchData()

}
// 加载
function onLoad() {
  loading.value = true
  console.log('onLoad');
  fetchData()
}

这是 API 定义:

export const getList = async (params: IQuery): Promise<BaseResponse<IData>> => await http.get('/list', {params})

这是我定义的类型:

interface BaseResponsePageInfo {
  total: number
  pageNum: number
  pageSize: number
  size: number
  nextPage: number
  isFirstPage: boolean
  isLastPage: boolean
}
interface BaseResponse<T> extends BaseResponsePageInfo {
  list: T[]
}
interface BaseQueryParams {
  pageNum: number
  pageSize: number
  orderBy?: string
}

根据采纳答案可以正常使用,但是会有下面的类型提示,在文件顶部加上// @ts-nocheck可以忽略类型提示
image.png

阅读 2.3k
1 个回答
import { ref } from 'vue'

interface BaseQueryParams {
  pageNum: number
  pageSize: number
  orderBy?: string
}

interface IData {
  // 数据类型定义
}

interface BaseResponsePageInfo {
  total: number
  pageNum: number
  pageSize: number
  size: number
  nextPage: number
  isFirstPage: boolean
  isLastPage: boolean
}

interface BaseResponse<T> extends BaseResponsePageInfo {
  list: T[]
}

// 定义 API 函数的类型
type ApiFunction<Q, T> = (params: Q) => Promise<BaseResponse<T>>

export function usePagination<Q extends BaseQueryParams, T>(apiFunction: ApiFunction<Q, T>, initialQueryParams: Q) {
  const refreshing = ref(false)
  const loading = ref(false)
  const finished = ref(false)
  const pageData = ref<BaseResponsePageInfo>()
  const data= ref<T[]>([])
  const queryParams = ref<Q>(initialQueryParams)

  // 获取数据
  async function fetchData() {
    try {
      loading.value = true
      const response = await apiFunction(queryParams.value)
      const { list, ...pageInfo } = response
      pageData.value = pageInfo
      if (refreshing.value) {
        data.value = list
      } else {
        data.value = data.value.concat(list)
      }
      if (pageInfo.isLastPage) {
        finished.value = true
      }
    } finally {
      loading.value = false
      refreshing.value = true
    }
  }

  // 刷新
  function onRefresh() {
    refreshing.value = true
    console.log('onRefresh');
    fetchData()
  }

  // 加载
  function onLoad() {
    loading.value = true
    console.log('onLoad');
    fetchData()
  }

  return {
    refreshing,
    loading,
    finished,
    pageData,
    data,
    queryParams,
    fetchData,
    onRefresh,
    onLoad
  }
}

使用:

import { usePagination } from './usePagination'
import { getAList } from './api'  
import { IQuery } from './query'  //查询参数类型

export default {
  setup() {
    const initialQueryParams: IQuery = {
      pageNum: 10,
      pageSize: 1,
      name: 'example'
    }
    const pagination = usePagination(getAList, initialQueryParams)

    // 在这里用 pagination 里的所有状态和方法
  

    return {
      ...pagination
    }
  }
}
推荐问题
logo
Microsoft
子站问答
访问
宣传栏