Vue3 Composition API 组合函数实现CRUD操作
在 Vue 应用的概念中,“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。当构建前端应用时,我们常常需要复用公共任务的逻辑。这里使用vue组合函数实现一个通用的crud功能
实现如下:函数名为useCRUD
,它接收一个名为apis
的对象参数,这个对象中包含了一系列用于执行CRUD操作的异步API方法(如pageFunc
、createFunc
、updateFunc
和delFunc
)。此函数主要目的是封装与数据管理相关的状态和方法,以便在组件中轻松实现数据的增删改查功能。
具体功能如下:
-
初始化状态变量:
searchForm
:使用ref
创建一个响应式对象,用于存储搜索表单的条件。page
:同样使用ref
创建,表示分页信息,包括每页大小(pageSize)、当前页码(pageNo)和总记录数(total)。tableLoading
:也是一个ref
对象,用来控制表格加载状态,true表示正在加载数据,false表示加载完成。tableData
:存放查询结果的数组,初始化为空数组。
-
定义操作方法:
reset
:重置搜索条件和分页信息,并重新查询第一页数据。queryPage
:通过useDebounceFn
进行防抖处理,延时300毫秒后执行sendRequest
函数以发起查询请求。这样可以避免用户频繁输入搜索条件时立即发送请求,提高性能。
-
异步请求逻辑:
sendRequest
:实际发起HTTP请求的方法,根据当前分页信息和搜索条件调用apis.pageFunc
获取数据,并更新tableLoading
状态以及page
和tableData
的数据。
-
表单编辑功能:
formVisible
:一个布尔值ref
,表示表单编辑界面是否可见。formData
:保存表单编辑内容的响应式对象。showForm
:显示表单编辑界面并填充数据的方法,传入需要编辑或新建的项。saveData
:处理表单提交事件,根据表单数据中的ID决定是调用apis.updateFunc
还是apis.createFunc
来执行更新或新增操作,完成后隐藏表单界面。deleteData
:删除指定ID的数据,通过调用apis.delFunc
实现。
最后,函数返回一组包含了上述所有状态和方法的对象,这些可以直接在组件内部解构赋值,方便在组件中实现对数据的CRUD操作。
use-crud.js 代码如下
import { ref } from 'vue';
import { useDebounceFn } from '@vueuse/core';
export default function useCRUD(apis) {
// 搜索表单
const searchForm = ref({});
// 分页信息
const page = ref({
pageSize: 10,
pageNo: 1,
total: 0,
});
// 表格加载loading
const tableLoading = ref(false);
// 表格数据
const tableData = ref([]);
// 重置查询
const reset = () => {
page.value.pageNo = 1;
searchForm.value = {};
queryPage();
};
// 分页查询 加了防抖
const queryPage = useDebounceFn(() => {
sendPageRequest();
}, 300);
/**
* 发送分页查询请求
*/
async function sendPageRequest() {
tableLoading.value = true;
const data = await apis.pageFunc({ ...page.value, ...searchForm.value });
tableLoading.value = false;
if (data) {
page.value.total = data.total ? data.total : 0;
tableData.value = data.list ? data.list : [];
}
}
// 编辑or新增-表单弹窗标识
const formVisible = ref(false);
// 表单数据
const formData = ref({});
// 显示表单弹窗
function showForm(item) {
formData.value = { ...item };
formVisible.value = true;
}
/**
* 保存数据 or 更新数据
*/
async function saveData() {
if (formData.value.id) {
await apis.updateFunc(formData.value);
} else {
await apis.createFunc(formData.value);
}
formVisible.value = false;
}
/**
* 删除数据
*/
async function deleteData(id) {
await apis.delFunc(id);
}
// 导出变量 方法
return {
searchForm,
tableLoading,
page,
tableData,
formData,
reset,
queryPage,
formVisible,
showForm,
saveData,
deleteData,
};
}
举例 use-crud在 user-list.vue 中的使用
<template>
<div>
<a-form layout="inline" :model="searchForm">
<a-form-item label="关键字">
<a-input style="width: 300px" v-model:value="searchForm.searchWord" placeholder="searchWord" />
</a-form-item>
<a-form-item>
<a-button type="primary" @click="reset"> 查询 </a-button>
<a-button @click="reset"> 重置 </a-button>
</a-form-item>
</a-form>
<a-table size="small" :pagination="false" :loading="tableLoading" :scroll="{ x: 1300 }" bordered :dataSource="tableData" :columns="userColumns">
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'action'">
<div>
<a-button @click="showForm(record)" size="small" type="link">编辑</a-button>
<a-popconfirm title="你确定要删除吗?" ok-text="确定" cancel-text="取消" @confirm="deleteData(record.id)">
<a-button size="small" danger type="link">删除</a-button>
</a-popconfirm>
</div>
</template>
</template>
</a-table>
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="['5', '10', '20', '30', '50', '100', '200']"
:defaultPageSize="page.pageSize"
v-model:current="page.pageNo"
v-model:pageSize="page.pageSize"
:total="page.total"
@change="queryPage"
@showSizeChange="queryPage"
:show-total="(total) => `共${total}条`"
/>
<EditForm v-model="formVisible" v-model:formData="formData" @close="formVisible = false" @save="saveData" />
</div>
</template>
<script setup>
import EditForm from './edit-form.vue';
import { ref } from 'vue';
import { userApi } from '../api/user-api.js';
// 这里导入 use-curd.js
import useCRUD from '../lib/use-curd.js';
const userColumns = ref([
{
title: '用户ID',
dataIndex: 'id',
minWidth: 180,
ellipsis: true,
},
{
title: '名称',
dataIndex: 'name',
minWidth: 170,
ellipsis: true,
},
{
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: 140,
},
]);
// 这里使用 useCRUD
const { searchForm, tableLoading, page, tableData, formData, reset, queryPage, formVisible, showForm, saveData, deleteData } = useCRUD({
pageFunc: userApi.getUserPage,
createFunc: userApi.getUserPage,
updateFunc: userApi.getUserList,
delFunc: userApi.getUserPage,
});
</script>
转载自:https://juejin.cn/post/7344967859054018623