在Vue.js 3中,"hook"(钩子)指的是一组特定的函数,用于在组件的生命周期中执行特定的操作。可以使用Composition API创建自定义钩子(Custom Hooks)。自定义钩子允许将可重用的逻辑封装在一个函数中,并在多个组件中共享。
要创建自定义钩子,请遵循以下步骤:
- 创建一个函数,命名为以 "use" 开头的名称,以表示它是一个钩子函数。例如,
useCustomHook。 - 在该函数内部定义您希望共享的逻辑,可以包括响应式数据、计算属性、方法等。
- 返回一个对象,其中包含需要在组件中使用的数据和方法。
- 在组件中使用自定义钩子函数。可以使用解构赋值或直接引用钩子函数返回的对象。
首先需要思考一个问题,这个 hook 接受什么参数,返回什么参数。现在没想好,不要紧,写着写着就知道了。
useTableData 中返回了 getTableData 函数。这个函数在成功之后,调用 setTableData 函数设置 table 的数据。
设置 tableData 中的参数有很多种情况,我们无法一一去控制,所以我们就需要把这部分的工作交给外界。
import { ref, reactive, nextTick } from 'vue'
function useTableData(tableParams) {
const getTableData = async () => {
const params = {
...tableParams
}
tableLoading.value = true
await request(params)
.then((res: any) => {
setTableData(res, tableData)
})
.finally(() => {
tableLoading.value = false
})
}
return { getTableData }
}
export default useTableData
表格分页器是标配,当分页器的page 变化,size 变化的时候,去请求新的数据
import { ref, reactive, nextTick } from 'vue'
function useTableData() {
const pagination = reactive({
total: 0,
page,
pageSize,
pageChange: async (page: number) => {
await getTableData()
},
sizeChange(pageSize: number) {
pagination.page = 1
pagination.pageSize = pageSize
getTableData()
}
})
return { pagination, getTableData }
}
export default useTableData
最后加上一些细节的优化
- 可以设置是否需要自动请求
- 把tableLoading, tableData 这两个数据传递出去
这是最终的实现效果
import { ref, reactive, nextTick } from 'vue'
interface Params {
getTableParams: Function
setTableData: Function
request: Function
autoRequest?: boolean
page?: number
pageSize?: number
pageName?: string
pageSizeName?: string
}
function useTableData({
getTableParams,
setTableData,
request,
autoRequest = true,
page = 1,
pageSize = 10,
pageName = 'page',
pageSizeName = 'page_size'
}: Params) {
const tableLoading = ref(false)
const tableData = ref([] as any[])
const tableParams = getTableParams()
const pagination = reactive({
total: 0,
page,
pageSize,
pageChange: async (page: number) => {
await getTableData()
},
sizeChange(pageSize: number) {
pagination.page = 1
pagination.pageSize = pageSize
getTableData()
}
})
const getTableData = async (page?: number, addParams?: any) => {
const params = {
...tableParams,
...getTableParams(),
...addParams
}
pagination.page = page || pagination.page
params[pageName] = pagination.page
params[pageSizeName] = pagination.pageSize
tableLoading.value = true
await request(params)
.then((res: any) => {
setTableData(res, tableData)
})
.finally(() => {
tableLoading.value = false
})
}
// 是否自动请求
if (autoRequest) {
getTableData()
}
return { tableLoading, tableData, pagination, getTableData }
}
export default useTableData