Vue3自定义useTable

背景

在后台管理系统中充斥着大量的搜索+表格的页面,需要重复定义 loadingpagetableData getData()等变量或方法,急需封装一个hook减少重复工作,useTable是最好的选择.

hook封装

hook接收请求地址,请求参数等参数,实现请求数据功能,并返回分页,数据类别,加载状态

formatParams:请求参数params解构后将不能动态获取form的变化,所有定义了formatParams方法用于修改入参

formatResult:处理请求返回的列表,并将格式化后的结果保存到tableData中,当然也你可以在onSuccess的回调中处理

onSuccess:请求成功的回调

pagination: 用于分页,分页改变后将自动重新请求

useList.js 完整代码

js 复制代码
import { onMounted, ref, watch } from 'vue'
import { post } from '@/utils/request'
import { message } from 'ant-design-vue'
/**
 * @name: useTable
 * @description: 获取列表数据
 */
export default function ({ url, params, formatParams, formatResult, onSuccess, immediate }) {
  const loading = ref(false)
  const pagination = ref({ total: 0, current: 1, pageSize: 10 })
  const tableData = ref([])
  //请求部分需结合具体项目修改
  const getData = async () => {
    loading.value = true
    const { code, data, msg, total } = await post(url, {
      ...(formatParams ? formatParams(params) : params),
      pageNum: pagination.value.current,
      pageSize: pagination.value.pageSize
    })
    loading.value = false
    if (code !== 0) return message.error(msg || '请求失败')
    tableData.value = formatResult ? formatResult(data) : data
    pagination.value.total = total
    onSuccess && onSuccess(data)
  }
  //分页改变
  watch(pagination, () => getData())
  //初始化请求
  onMounted(() => immediate && getData())

  return { loading, tableData, pagination, getData }
}

使用示例

UI框架使用Ant Design Vue,示例省略部分代码

html 复制代码
<template>
  <a-form :model="formState">
    <a-form-item name="key" label="名称">
      <a-input v-model:value="formState.name" placeholder="请输入" />
    </a-form-item>
    <a-form-item name="stdate" label="日期范围">
      <a-range-picker v-model:value="formState['range-picker']" />
    </a-form-item>
  </a-form>
  <a-table :loading="loading" :columns="columns" :data-source="tableData" :pagination="pagination" @change="(page) => (pagination = page)" />
</template>
<script setup>
import { ref } from 'vue'
import columns from './columns'
import useTable from './useTable'
const formState = ref({})
const { loading, tableData, pagination, getData } = useTable({
  url: '/api/xxxxx', //请求路径
  immediate: true, //立即请求
  params: formState.value, //请求入参 此处必须为ref对象,且不能解构
  formatParams: (params) => { //格式化入参
    return {
      ...params,
      startDate: params['range-picker'][0],
      endDate: params['range-picker'][1]
    }
  },
  formatResult: (res) => {  //格式化结果
    //...
  },
  onSuccess: (res) => {     //成功回调
    //...
  }
})
</script>

对比

在不使用useTable的情况下,代码如下,可以看出封装useTable大大减少重复工作,不用在每个表格下定义分页和loading,而且代码更简洁易懂。

html 复制代码
<template>
<a-form :model="formState">
...
</a-form>
<a-table
    :loading="loading"
    :columns="columns"
    :data-source="tableData"
    :pagination="page"
    @change="onPageChange"
  />
</template>  
<script setup>
import { ref, getData } from 'vue'
import useTable from './useTable'
import columns from './columns'
import { post } from '@/utils/request'
const loading = ref(false)
const tableData = ref([])
const formState = ref({})
const page = ref({ total: 0, current: 1, pageSize: 10 })
//请求数据
const getData = async () => {
  loading.value = true
  const { code, data, total } = await post('/api/xxxx', {
    ...formState.value,
    startDate: formState.value['range-picker'][0],
    endDate: formState.value['range-picker'][1],
    pageNum: page.value.current,
    pageSize: page.value.pageSize
  })
  loading.value = false
  if (code !== 0) return
  tableData.value = data
  page.value.total = total
}
//分页改变
const onPageChange = ({ current, pageSize }) => {
  page.value.current = current
  page.value.pageSize = pageSize
  getData()
}
//初始化请求
onMounted(() => getData())
</script>

结尾

如有更好的意见或建议,欢迎留言探讨

相关推荐
并不会33 分钟前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
衣乌安、37 分钟前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜37 分钟前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师39 分钟前
CSS的三个重点
前端·css
耶啵奶膘2 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^4 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie4 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic5 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿5 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具5 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端