使用Vue3 hooks封装一个表格操作的方法

1,469 阅读2分钟

Vue3相比于Vue2改变了很多,Vue3中没有了this,组合式API能让我们更容易的抽离代码逻辑,Vue3中的hooks就是函数的一种写法,可以将文件的一些单独功能的js代码抽离出来,放到单独的js文件中。

在进行业务开发时,最常见的就是表格和表单,这次先介绍表格操作hooks。一般表格操作都包括表格数据获取、表格分页信息、表格分页切换、表格loading、表格数据搜索功能,这些功能都是固定且必需的。如果每个表格页面我们都写一遍这一套方法,那么将会产生很多相似度高的代码,因此,我们可以使用hooks抽离这些逻辑。

首先,我们都知道,无论内部接口逻辑如何,我们的流程都是,传递参数请求接口->获取接口数据,因此我们只需要关注输入输出,即这个hooks方法我们只需要传递请求接口方法和请求参数,返回统一的数据格式内容。src目录下新建hooks目录,然后新建useTable.js文件,输入以下代码。

import {
  reactive, toRefs,
} from 'vue';
import { debounce } from 'lodash';
import { ElMessage } from 'element-plus';

/**
 * @description table操作方法封装
 * @param {Function} api 表格列表数据接口
 * @param {Object} searchParam 表格查询参数
 */
export const useTable = (api, searchParam = {}) => {

  const state = reactive({
    loading: false,
    tableData: [],
    page: {
      current: 1,
      totalCount: 1,
      size: 15,
      sizeOption: [15, 20, 30, 50, 200],
    },
  });

  // 获取表格列表数据 
  const loadList = async (params = {
    current: state.page.current,
    size: state.page.size,
    ...searchParam,
  }) => {

    state.loading = true;
    const {
      resultCode, data, msg,
    } = await api(params).catch((e) => e);
    state.loading = false;
    if (resultCode === 0) {

      state.tableData = data.records;
      state.page.totalCount = data.totalCount;

    } else if (msg) {

      ElMessage.error(msg);

    }

  };

  // 分页切换方法
  const handleSizeChange = (val) => {

    state.page.size = val;
    loadList();

  };

  // 表格数据搜索, 防抖(需安装lodash)
  const searchData = debounce((loadList) => {

    loadList();

  }, 500);

  // 返回相关变量与方法
  return {
    ...toRefs(state),
    loadList,
    handleSizeChange,
    searchData,
  };

};

使用表格hooks,在对应页面引入hooks

import { useTable } from '@/hooks/useTable';
// 引入接口Api
import { getCusList } from '@/api/modules/customer';

const searchParam = reactive({ keyword: '' });
// 使用自定义table hooks
const {
  tableData, page, loading, loadList, handleSizeChange, searchData,
} = useTable(getCusList, searchParam);

我们只需要传递接口api与请求参数,就可以直接使用了

<template>
  <div class="customer">
    <div class="operation">
      <div>
        <el-input
          v-model="searchParam.keyword"
          placeholder="搜索"
          :prefix-icon="Search"
          clearable
          @change="searchData(loadList)"
        />
      </div>
    </div>
    <el-table
      v-loading="loading"
      stripe
      :data="tableData"
      @selection-change="selectionHandle"
    >
      <el-table-column type="selection" />
      <el-table-column
        label="客户名称"
        prop="cusName"
      />
      <el-table-column
        label="录入时间"
        prop="gmtCreate"
      />
      <el-table-column
        label="备注"
        prop="memo"
      />
    </el-table>
    <el-pagination
      v-model:current-page="page.current"
      :page-size="page.size"
      :page-sizes="page.sizeOption"
      layout="->, total, sizes, prev, pager, next, jumper"
      :total="page.totalCount"
      style="margin-top: 20px"
      @size-change="handleSizeChange"
      @current-change="searchData(loadList)"
    />
  </div>
</template>

这样我们就能减少很多代码了,当然,这只是一个参考,可以根据自己项目业务自行扩展修改,但是本质都是一样,控制好输入输出,我也是刚使用Vue3不久,有写得不好或者错误的还希望能帮我指出,谢谢大家。