基于AVue的二次封装:快速构建后台管理系统的CRUD方案

ops/2025/2/26 2:14:09/

基于AVue的二次封装:快速构建后台管理系统的CRUD方案

在开发后台管理系统时,表格是常见的组件之一。然而,使用原生的Element Plus实现CRUD(增删改查)功能往往需要编写大量重复代码,过程繁琐。即使借助类似AVue这样的数据驱动视图框架,虽然能简化开发,但配置和使用上仍不够简洁。因此,我对AVue进行了二次封装,打造了一个更高效的CRUD组件——f-crud,以提升开发效率。

本文将详细介绍封装思路、实现代码以及使用方法,并附上效果图和建议。


一、封装目标

  1. 简化配置:通过统一的接口和配置项,减少开发者重复编写CRUD逻辑的负担。
  2. 功能完整:支持表格展示、搜索、分页、增删改查等核心功能。
  3. 灵活扩展:支持插槽自定义列渲染,适配不同业务场景。
  4. 快速上手:只需简单配置即可实现完整的CRUD功能。

二、实现方案

1. 使用层代码 (f-crud 使用示例)

以下是基于f-crud组件的使用示例,直接实现一个日志管理页面:

<template><div class="app-log-page flex pt-[10px]"><f-crudref="fcrud":option="option":operate="operate":formProps="formProps"v-model="form"class="p-[12px] w-full"><!-- 自定义列渲染:显示应用Logo --><template #appLogoUrl="{ row }"><img v-if="row.appLogoUrl" :src="row.appLogoUrl" alt="" width="60px" height="60px"></template><!-- 可选插槽:自定义操作按钮 --><template #menuLeft="{ row }"></template><template #menu="{ row }"></template><template #search-menu="{ row }"></template></f-crud></div>
</template><script lang="ts" setup>
import { ref, onMounted } from "vue";// 搜索表单数据
const form = ref({ status: "", userName: "", includedSub: true });// CRUD 接口配置
const operate = ref({getList: "/getItalentSyncLogList",postUrl: "/admin/data/area",putUrl: "/admin/data/area",delUrl: "/admin/data/area/",
});const fcrud = ref(null);// 分页等基础属性
const formProps = ref({ pageSize: 10 });// 表格及表单配置
const option = () => ({border: true,searchSpan: 4,searchLabelWidth: 1,searchIcon: true,searchGutter: 20,searchMenuSpan: 7,searchIndex: 5,indexWidth: 60,emptyBtnText: "重置",columnBtn: false,index: true,align: "center",column: [{ label: "北森修改人", prop: "operatorName" },{ label: "动作", prop: "actionTypeName" },{ label: "类型", prop: "typeName" },{ label: "同步前组织名称", prop: "name" },{ label: "同步前信息", prop: "beforeUpdate", showOverflowTooltip: true, overHidden: true, width: 250 },{ label: "同步后信息", prop: "afterUpdate", showOverflowTooltip: true, overHidden: true, width: 250 },{ label: "创建时间", prop: "createTime", width: 200, align: "center" },// 搜索字段(隐藏在表格中){ prop: "beforeUpdate", search: true, hide: true, placeholder: "修改前信息搜索", width: 250 },{ prop: "afterUpdate", search: true, hide: true, placeholder: "修改后信息搜索" },{prop: "actionType",placeholder: "操作类型",search: true,hide: true,type: "select",dicData: [{ label: "新增", value: "1" },{ label: "修改", value: "2" },{ label: "禁用", value: "3" },],},],
});// 初始化加载数据
onMounted(() => {fcrud.value.getList();
});
</script><style lang="scss" scoped></style>

效果图

效果图

通过以上代码,只需配置option(表格和表单结构)、operate(接口地址)和formProps(分页参数),即可实现完整的增删改查功能。


2. 封装层代码 (f-crud.vue)

f-crud组件基于AVue的avue-crud,对其进行封装,统一处理数据请求、分页、表单等逻辑:

<template><div><avue-crudv-loading="data.listLoading"@search-reset="resetList"element-loading-text="Loading..."element-loading-spinner="svg"ref="crud"v-model:page="data.page"v-model:search="data.tForm"v-model="data.tForm"@row-update="rowEdit"@row-save="rowSave"@search-change="handleFilter"@size-change="sizeChange"@current-change="currentChange"@row-del="rowDelete"@refreshChange="handleRefreshChange":data="data.list":option="option()":beforeOpen="beforeOpen"@selection-change="selectionChange"><template #menu="{ row }"><slot name="menu" :row="row"></slot></template><template #menu-left="{ row }"><slot name="menuLeft" :row="row"></slot></template><template #search-menu="{ row }"><slot name="search-menu" :row="row"></slot></template><template #appLogoUrl="{ row }"><slot name="appLogoUrl" :row="row"></slot></template></avue-crud></div>
</template><script setup lang="ts">
import { reactive, watch, ref, onMounted } from "vue";
import { useTable } from "@/utils/use-table";interface Props<T = any> {operate: T;modelValue: T;formProps?: T;option: T;
}const props = withDefaults(defineProps<Props>(), {operate: { getList: "", postUrl: "", putUrl: "", delUrl: "" },modelValue: {},formProps: {},option: () => {},
});const crud = ref<any>(null);
const data = reactive({page: {total: 0,currentPage: 1,pageSize: props.formProps.pageSize || 20,isAsc: false,},listLoading: true,getList: props.operate.getList,postUrl: props.operate.postUrl,putUrl: props.operate.putUrl,delUrl: props.operate.delUrl,props: props.formProps,query: {},list: [],tForm: {},
});const emit = defineEmits(["update:modelValue", "selectionChange"]);const beforeOpen = (done: Function) => {crud.value.dicInit();done();
};watch(() => data.tForm, (value) => emit("update:modelValue", value));onMounted(() => {data.tForm = props.modelValue;
});const selectionChange = (list) => emit("selectionChange", list);const resetList = () => getList();const { getList, rowSave, rowEdit, rowDelete, handleFilter, handleRefreshChange, currentChange, sizeChange } =useTable(data);defineExpose({ getList, rowSave, rowEdit, rowDelete, handleFilter, handleRefreshChange, currentChange, sizeChange, data, crud });
</script>

3. 逻辑层代码 (use-table.ts)

use-table是一个独立的工具函数,封装了CRUD的核心逻辑,包括数据获取、分页处理和表单操作:

import { ElMessageBox, ElNotification } from "element-plus";
import Api from "@/api/common";export function useTable(data: any) {const getList = (params: any = {}) => {params = Object.assign(params, data.tForm, data.props || {});data.listLoading = true;return Api.getList({ ...params, pageNum: data.page.currentPage, pageSize: data.page.pageSize },data).then((response: any) => {data.list = response.data.resultData?.list || response.data.resultData;data.page.total = response.data.resultData?.total;data.listLoading = false;});};const handleFilter = (param: any, done: Function) => {data.page.currentPage = 1;getList(param);done && done();};const handleRefreshChange = (current?: number) => {if (current) data.page.currentPage = current;getList();};const sizeChange = (pageSize: number) => {data.page.pageSize = pageSize;handleRefreshChange();};const currentChange = (current: number) => {data.page.currentPage = current;handleRefreshChange();};const rowSave = async (form: any, done: Function, loading: Function) => {if (data.props) Object.assign(form, data.props);await Api.post(form, data).then(() => {ElNotification({ message: "操作成功", type: "success" });done();loading();handleRefreshChange();}).catch(loading);};const rowEdit = async (form: any, index: number, done: Function, loading: Function) => {if (data.props) Object.assign(form, data.props);await Api.put(form, data).then(() => {ElNotification({ message: "操作成功", type: "success" });done && done();loading && loading();handleRefreshChange();}).catch(loading);};const rowDelete = (form: any) => {ElMessageBox.confirm("此操作将永久删除该数据,是否继续?", "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning",}).then(async () => {await Api.del(form.id, data);ElNotification({ message: "操作成功", type: "success" });handleRefreshChange();});};return { getList, rowSave, rowEdit, rowDelete, handleFilter, handleRefreshChange, currentChange, sizeChange };
}

4. 请求层代码 (common.ts)

封装Axios请求,提供统一的接口调用方法:

import request from "@/plugins/axios";const common = {getList: (params: {}, { getList = "", id = "" }) =>request({ url: getList + id, method: "get", params }),post: (data: {}, { postUrl = "", postMethod = "post" }) =>request({ url: postUrl, method: postMethod, data }),del: (id: string, { delUrl = "", delMethod = "delete" }, params = {}) =>request({ url: delUrl + id, method: delMethod, params }),put: (data: {}, { putUrl = "", putMethod = "put" }) =>request({ url: putUrl, method: putMethod, data }),
};export default common;

三、使用方法

  1. 引入组件:将f-crud.vue注册到项目中。
  2. 配置参数
    • option:定义表格列、搜索字段和样式。
    • operate:提供CRUD接口地址。
    • formProps:设置分页等额外参数。
  3. 绑定数据:通过v-model绑定搜索表单数据。
  4. 自定义扩展:通过插槽自定义列渲染或按钮。

四、优点与建议

优点

  • 高效开发:只需少量配置即可实现完整CRUD功能。
  • 代码复用:逻辑抽离到use-table,便于维护和复用。
  • 灵活性:支持插槽和AVue原生属性,满足复杂需求。

建议

如果对样式要求不高,可以考虑使用百度的AMIS低代码框架。AMIS提供更强大的CRUD功能和更高的开发效率,尤其适合快速原型开发。

  • AVue官网:https://avuejs.com/
  • AMIS官网:https://aisuda.bce.baidu.com/amis/zh-CN/docs/index

希望这个封装方案能帮助你更高效地构建后台管理系统!如果有其他需求,可以随时交流优化方案。


这篇文章基于xai进行重新编辑


http://www.ppmy.cn/ops/161328.html

相关文章

mysql的主从配置

#mysql数据库 #主从 MySQL数据库主从配置 1.MySQL主从介绍 MySQL 主从又叫做 Replication、AB 复制。简单讲就是 A 和 B 两台机器做主 从后&#xff0c;在 A 上写数据&#xff0c;另外一台 B 也会跟着写数据&#xff0c;两者数据实时同步的。 MySQL 主从是基于 binlog 的&…

WebGL 加载 .obj 格式文件

摘要 WebGL 作为一种在网页上实现高性能 3D 图形渲染的技术&#xff0c;为网页开发者提供了强大的工具。而 .obj 文件是一种常见的 3D 模型文件格式&#xff0c;被广泛应用于 3D 设计和开发领域。本文将深入探讨如何使用 WebGL 加载 .obj 格式的文件&#xff0c;涵盖了 .obj 文…

跟着李沐老师学习深度学习(十四)

注意力机制&#xff08;Attention&#xff09; 引入 心理学角度 动物需要在复杂环境下有效关注值得注意的点心理学框架&#xff1a;人类根据随意线索和不随意线索选择注意力 注意力机制 之前所涉及到的卷积、全连接、池化层都只考虑不随意线索而注意力机制则显示的考虑随意…

怎么让电脑上的摄像头无绿幕使用背景虚化/虚拟背景、视频无绿幕使用背景虚化、虚拟摄像头无绿幕背景虚化

参考&#xff1a; http://t.csdnimg.cn/EKHFG https://github.com/aisegmentcn/aisegment_obs_plugin https://obsproject.com/forum/resources/virtual-background-by-aisegment.1546/ 腾讯会议中是可以使用虚拟背景的&#xff0c;但是其他视频会议软件没有&#xff0c;那怎么…

C++ 编程语言简介

C 是一种通用编程语言&#xff0c;它是作为 C 语言的增强而开发的&#xff0c;以包含面向对象的范例。它是一种命令式和编译语言。 C 是一种高级的通用编程语言&#xff0c;专为系统和应用程序编程而设计。它由贝尔实验室的 Bjarne Stroustrup 于 1983 年开发&#xff0c;作为…

ssh被暴力访问了,怎么拦截ip

目录 1. 使用 iptables 拦截 IP 2. 使用 firewalld 拦截 IP 3. 修改 SSH 配置 要拦截暴力访问的 IP 地址&#xff08;如 10.242.249.8&#xff09;&#xff0c;你可以通过以下几种方法来实现&#xff1a; 1. 使用 iptables 拦截 IP 如果你的系统使用 iptables&#xff0c;可…

DeepSeek 全面分析报告

引言 DeepSeek 是一款由中国人工智能初创公司 DeepSeek 开发的大型语言模型 (LLM)&#xff0c;于 2025 年 1 月发布&#xff0c;迅速成为全球人工智能领域的一匹黑马。DeepSeek 不仅在性能上可与 OpenAI、Google 等巨头的模型相媲美&#xff0c;而且其训练成本和运行效率都显著…

蓝桥杯 Java B 组之最短路径算法(Dijkstra、Floyd-Warshall)

Day 2&#xff1a;最短路径算法&#xff08;Dijkstra、Floyd-Warshall&#xff09; &#x1f4d6; 一、最短路径算法简介 最短路径问题是图论中的经典问题&#xff0c;主要用于求解 单源最短路径 或 多源最短路径。在实际应用中&#xff0c;最短路径广泛应用于 导航系统、网络…