最近在用 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可以忽略类型提示
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
}
}
}
非常感谢您的回答,怪我没有把问题说明白。
我希望是能把 api 传入 hook 中,因为每个页面的 api 是不一样的。比如
usePagination(getAList)
usePagination(getBList)
然后这个要怎么做,或者说怎么定义类型?
用泛型即可