Vue3的CRUD模版(附Demo)

目录

  • 前言
  • 模版

前言

用惯Vue2之后,在碰Vue3后,整体还是有所区别

此文主要做一个回顾总结

假设界面如下:

在这里插入图片描述

可CRUD,对应的新增 添加一些必选项:

在这里插入图片描述

其中数据库的设计如下:
在这里插入图片描述

模版

对应需要注意参数位置、初始化表单,重置表单等位置

其首页界面如下:

<template><ContentWrap><!-- 搜索工作栏 --><el-formclass="-mb-15px":model="queryParams"ref="queryFormRef":inline="true"label-width="68px"><el-form-item label="企业名称" prop="enterpriseName"><el-inputv-model="queryParams.enterpriseName"placeholder="请输入企业名称"clearable@keyup.enter="handleQuery"class="!w-240px"/></el-form-item><el-form-item label="信用代码" prop="creditCode"><el-inputv-model="queryParams.creditCode"placeholder="请输入信用代码"clearable@keyup.enter="handleQuery"class="!w-240px"/></el-form-item><el-form-item label="注册人" prop="registrant"><el-inputv-model="queryParams.registrant"placeholder="请输入注册人"clearable@keyup.enter="handleQuery"class="!w-240px"/></el-form-item><el-form-item label="联系电话" prop="contactNumber"><el-inputv-model="queryParams.contactNumber"placeholder="请输入联系电话"clearable@keyup.enter="handleQuery"class="!w-240px"/></el-form-item><el-form-item label="创建时间" prop="createTime"><el-date-pickerv-model="queryParams.createTime"value-format="YYYY-MM-DD HH:mm:ss"type="daterange"start-placeholder="开始日期"end-placeholder="结束日期":default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"class="!w-240px"/></el-form-item><el-form-item label="审批通过与否" prop="status"><el-selectv-model="queryParams.status"placeholder="请选择审批通过与否"clearableclass="!w-240px"><el-optionv-for="dict in getStrDictOptions(DICT_TYPE.DSP_PASS_OR_NOT)":key="dict.value":label="dict.label":value="dict.value"/></el-select></el-form-item><el-form-item><el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button><el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button><el-buttontype="primary"plain@click="openForm('create')"v-hasPermi="['dangerous:enterprise-registry:create']"><Icon icon="ep:plus" class="mr-5px" /> 新增</el-button><el-buttontype="success"plain@click="handleExport":loading="exportLoading"v-hasPermi="['dangerous:enterprise-registry:export']"><Icon icon="ep:download" class="mr-5px" /> 导出</el-button></el-form-item></el-form></ContentWrap><!-- 列表 --><ContentWrap><el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"><el-table-column label="序号" align="center" prop="id" /><el-table-column label="企业名称" align="center" prop="enterpriseName" /><el-table-column label="信用代码" align="center" prop="creditCode" /><el-table-column label="注册人" align="center" prop="registrant" /><el-table-column label="联系电话" align="center" prop="contactNumber" /><el-table-columnlabel="创建时间"align="center"prop="createTime":formatter="dateFormatter"width="180px"/><el-table-column label="审批通过与否" align="center" prop="status"><template #default="scope"><dict-tag :type="DICT_TYPE.DSP_PASS_OR_NOT" :value="scope.row.status" /></template></el-table-column><el-table-column label="操作" align="center"><template #default="scope"><el-buttonlinktype="primary"@click="openForm('update', scope.row.id)"v-hasPermi="['dangerous:enterprise-registry:update']">编辑</el-button><el-buttonlinktype="danger"@click="handleDelete(scope.row.id)"v-hasPermi="['dangerous:enterprise-registry:delete']">删除</el-button></template></el-table-column></el-table><!-- 分页 --><Pagination:total="total"v-model:page="queryParams.pageNo"v-model:limit="queryParams.pageSize"@pagination="getList"/></ContentWrap><!-- 表单弹窗:添加/修改 --><EnterpriseRegistryForm ref="formRef" @success="getList" />
</template><script setup lang="ts">
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { EnterpriseRegistryApi, EnterpriseRegistryVO } from '@/api/dangerous/enterpriseregistry'
import EnterpriseRegistryForm from './EnterpriseRegistryForm.vue'/** 企业信息 列表 */
defineOptions({ name: 'EnterpriseRegistry' })const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化const loading = ref(true) // 列表的加载中
const list = ref<EnterpriseRegistryVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({pageNo: 1,pageSize: 10,enterpriseName: undefined,creditCode: undefined,registrant: undefined,contactNumber: undefined,createTime: [],status: undefined,
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中/** 查询列表 */
const getList = async () => {loading.value = truetry {const data = await EnterpriseRegistryApi.getEnterpriseRegistryPage(queryParams)list.value = data.listtotal.value = data.total} finally {loading.value = false}
}/** 搜索按钮操作 */
const handleQuery = () => {queryParams.pageNo = 1getList()
}/** 重置按钮操作 */
const resetQuery = () => {queryFormRef.value.resetFields()handleQuery()
}/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {formRef.value.open(type, id)
}/** 删除按钮操作 */
const handleDelete = async (id: number) => {try {// 删除的二次确认await message.delConfirm()// 发起删除await EnterpriseRegistryApi.deleteEnterpriseRegistry(id)message.success(t('common.delSuccess'))// 刷新列表await getList()} catch {}
}/** 导出按钮操作 */
const handleExport = async () => {try {// 导出的二次确认await message.exportConfirm()// 发起导出exportLoading.value = trueconst data = await EnterpriseRegistryApi.exportEnterpriseRegistry(queryParams)download.excel(data, '企业信息.xls')} catch {} finally {exportLoading.value = false}
}/** 初始化 **/
onMounted(() => {getList()
})
</script>

其表单内容如下:

<template><Dialog :title="dialogTitle" v-model="dialogVisible"><el-formref="formRef":model="formData":rules="formRules"label-width="100px"v-loading="formLoading"><el-form-item label="企业名称" prop="enterpriseName"><el-input v-model="formData.enterpriseName" placeholder="请输入企业名称" /></el-form-item><el-form-item label="信用代码" prop="creditCode"><el-input v-model="formData.creditCode" placeholder="请输入信用代码" /></el-form-item><el-form-item label="注册人" prop="registrant"><el-input v-model="formData.registrant" placeholder="请输入注册人" /></el-form-item><el-form-item label="联系电话" prop="contactNumber"><el-input v-model="formData.contactNumber" placeholder="请输入联系电话" /></el-form-item><el-form-item label="审批通过与否" prop="status"><el-radio-group v-model="formData.status"><el-radiov-for="dict in getStrDictOptions(DICT_TYPE.DSP_PASS_OR_NOT)":key="dict.value":label="dict.value">{{ dict.label }}</el-radio></el-radio-group></el-form-item></el-form><template #footer><el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button><el-button @click="dialogVisible = false">取 消</el-button></template></Dialog>
</template>
<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { FormRules } from 'element-plus'
import { EnterpriseRegistryApi, EnterpriseRegistryVO } from '@/api/dangerous/enterpriseregistry'/** 企业信息 表单 */
defineOptions({ name: 'EnterpriseRegistryForm' })const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const formType = ref('') // 表单的类型:create - 新增;update - 修改
const formData = ref({id: undefined,enterpriseName: undefined,creditCode: undefined,registrant: undefined,contactNumber: undefined,status: undefined,
})
const formRules = reactive<FormRules>({enterpriseName: [{ required: true, message: '企业名称不能为空', trigger: 'blur' }],creditCode: [{ required: true, message: '信用代码不能为空', trigger: 'blur' }],registrant: [{ required: true, message: '注册人不能为空', trigger: 'blur' }],contactNumber: [{ required: true, message: '联系电话不能为空', trigger: 'blur' }],status: [{ required: false, message: '联系电话不能为空', trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref/** 打开弹窗 */
const open = async (type: string, id?: number) => {dialogVisible.value = truedialogTitle.value = t('action.' + type)formType.value = typeresetForm()// 修改时,设置数据if (id) {formLoading.value = truetry {formData.value = await EnterpriseRegistryApi.getEnterpriseRegistry(id)} finally {formLoading.value = false}}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {// 校验表单await formRef.value.validate()// 提交请求formLoading.value = truetry {const data = formData.value as unknown as EnterpriseRegistryVOif (formType.value === 'create') {await EnterpriseRegistryApi.createEnterpriseRegistry(data)message.success(t('common.createSuccess'))} else {await EnterpriseRegistryApi.updateEnterpriseRegistry(data)message.success(t('common.updateSuccess'))}dialogVisible.value = false// 发送操作成功的事件emit('success')} finally {formLoading.value = false}
}/** 重置表单 */
const resetForm = () => {formData.value = {id: undefined,enterpriseName: undefined,creditCode: undefined,registrant: undefined,contactNumber: undefined,status: undefined,}formRef.value?.resetFields()
}
</script>

对应后端的接口传输如下:

import request from '@/config/axios'// 企业信息 VO
export interface EnterpriseRegistryVO {id: number // 序号enterpriseName: string // 企业名称creditCode: string // 信用代码registrant: string // 注册人contactNumber: number // 联系电话status: string // 审批通过与否
}// 企业信息 API
export const EnterpriseRegistryApi = {// 查询企业信息分页getEnterpriseRegistryPage: async (params: any) => {return await request.get({ url: `/dangerous/enterprise-registry/page`, params })},// 查询企业信息详情getEnterpriseRegistry: async (id: number) => {return await request.get({ url: `/dangerous/enterprise-registry/get?id=` + id })},// 新增企业信息createEnterpriseRegistry: async (data: EnterpriseRegistryVO) => {return await request.post({ url: `/dangerous/enterprise-registry/create`, data })},// 修改企业信息updateEnterpriseRegistry: async (data: EnterpriseRegistryVO) => {return await request.put({ url: `/dangerous/enterprise-registry/update`, data })},// 删除企业信息deleteEnterpriseRegistry: async (id: number) => {return await request.delete({ url: `/dangerous/enterprise-registry/delete?id=` + id })},// 导出企业信息 ExcelexportEnterpriseRegistry: async (params) => {return await request.download({ url: `/dangerous/enterprise-registry/export-excel`, params })},
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/688422.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

排序1——直接插入排序,希尔排序,选择排序,堆排序

1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录…

idea中使用git拉取代码详细操作

注意&#xff1a;解决 Git拉取代码和本地代码丢失问题请点这里查看 以textGit文件为例&#xff1a; 下图&#xff1a;本地刚拉取远程的代码 git上的代码 1、在本地对代码进行修改 2、在git上对代码进行修改&#xff0c;模拟其他人对此文件的提交修改 3、拉取远程代码 4、合并自…

智慧校园的主要功能是什么

随着信息化的发展&#xff0c;智慧校园的应用已经屡见不鲜。智慧校园是新技术与新科技落地的典型案例。智慧校园完善了校园信息化建设体系&#xff0c;推动了教育水平的提升&#xff0c;以下是智慧校园实现的几个比较典型的功能&#xff1a; 1.数字化办公 毋庸置疑&#xff0…

Remix Client/Server 架构

Remix 框架是服务端渲染架构&#xff0c;当路由请求时生成 HTML 并返回浏览器。这种 SSR 是如何实现的呢&#xff1f;如果不使用 Remix 这种框架&#xff0c;可以在服务器段启动一个无头浏览器进行页面渲染并返回&#xff0c;代价就是要在服务器上启动一个 Chrome 服务&#xf…

第12节 第二种shellcode编写实战(1)

我最近在做一个关于shellcode入门和开发的专题课&#x1f469;&#x1f3fb;‍&#x1f4bb;&#xff0c;主要面向对网络安全技术感兴趣的小伙伴。这是视频版内容对应的文字版材料&#xff0c;内容里面的每一个环境我都亲自测试实操过的记录&#xff0c;有需要的小伙伴可以参考…

三层交换机与路由器连通上网实验

三层交换机是一种网络交换机&#xff0c;可以实现基于IP地址的高效数据转发和路由功能&#xff0c;通常用于大型企业、数据中心和校园网络等场景。此外&#xff0c;三层交换机还支持多种路由协议&#xff08;如OSPF、BGP等&#xff09;&#xff0c;以实现更为复杂的网络拓扑结构…

2024年第九届“数维杯”大学生数学建模挑战赛B题

第一个问题为&#xff1a;正己烷不溶物对热解产率是否产生显著影响&#xff1f; 第一个问题&#xff1a;正己烷不溶物(INS)对热解产率是否产生显著影响&#xff1f; 解析&#xff1a;正己烷不溶物(INS)主要是由生物质和煤中的非挥发性物质组成&#xff0c;它们在共热解过程中会…

通信指挥类装备(多链路聚合设备)-应急通信指挥解决方案

现场通信指挥系统是一种功能全面的便携式音视频融合指挥通信平台&#xff0c;可实现现场应急救援指挥、多种通信手段融合、现场通信组网等功能&#xff0c;是现场指挥系统的延伸。 多链路聚合设备&#xff0c;是一款通信指挥类装备&#xff0c;具有 4G/5G&#xff0c;专网&…

Cloudera的简介及安装部署

简介 Cloudera是一家位于美国的软件公司&#xff0c;成立于2008年&#xff0c;专注于为企业客户提供基于Apache Hadoop的软件、支持、服务以及培训。Cloudera的开源Apache Hadoop发行版&#xff0c;即Cloudera Distribution including Apache Hadoop&#xff08;CDH&am…

AI赋能未来教育:中国教学科研新蓝图

设“人啊 前言 回顾过去&#xff0c;传统的教育模式以知识灌输和应试为主&#xff0c;虽培养出大量人才&#xff0c;但也存在着学生创新能力不足、实践经验缺乏等问题。随着时代的进步和科技的发展&#xff0c;传统教育模式已难以满足当今社会对人才的需求。然而&#xff0c;当…

阿里云和AWS负载均衡服务对比分析

在云计算时代,负载均衡作为一种关键的网络基础设施,承担着在多个服务器之间分发网络流量的重要任务。作为全球两大主要的云服务提供商,阿里云和Amazon Web Services(AWS)都提供了强大的负载均衡解决方案。本文将从性能、功能、可用性和成本等方面对两者进行对比分析。我们九河云…

Html + Express 实现大文件分片上传、断点续传、秒传

在日常的网页开发中&#xff0c;文件上传是一项常见操作。通过文件上传技术&#xff0c;用户可以将本地文件方便地传输到Web服务器上。这种功能在许多场景下都是必不可少的&#xff0c;比如上传文件到网盘或上传用户头像等。 然而&#xff0c;当需要上传大型文件时&#xff0c;…

不容错过的秘籍:JavaScript数组的创建和使用详解

在编程的世界里&#xff0c;数据是构建一切的基础。而在JavaScript中&#xff0c;有一种特殊且强大的数据结构&#xff0c;它就是——数组。 今天&#xff0c;我们就来一起探索数组的奥秘&#xff0c;从创建到使用&#xff0c;一步步掌握这个重要的工具。 一、什么是数组 数…

pycharm滚轮放大字体

进入settings&#xff0c;然后按从左到右的箭头顺序依次点击即可

Win10鼠标右键新增软件快速打开项

1、cmd 运行 regedit 2、找到该位置的shell文件夹 3、在shell文件夹下创建需要添加的软件名的文件夹&#xff0c;并修改相关信息 4、新建子文件夹command&#xff0c;并修改相关信息 5、效果

斯坦福李飞飞最新对话:AI不会对人类造成“灭绝性危机” | 最新快讯

美国斯坦福大学教授、美国国家工程院院士李飞飞&#xff08;来源&#xff1a;斯坦福大学账号&#xff09; 北京时间 5 月 10 日凌晨举行的 Bloomberg Tech 活动上&#xff0c;著名华人计算机科学家、美国斯坦福大学教授李飞飞&#xff08;Fei-Fei Li&#xff09;与彭博社 Emily…

【NodeMCU实时天气时钟温湿度项目 4】通过NTPClient库获取实时网络时间并显示在TFT屏幕上

今天是【实时天气时钟温湿度项目】第四专题&#xff0c;主要内容是&#xff1a;学习导入NTPClient库&#xff0c;通过这个库获取实时网络时间&#xff0c;显示在1.3寸TFT液晶屏幕上。此前三个专题&#xff0c;请选择查看以下链接。 第一专题内容&#xff0c;请参考 【N…

C语言神奇的经典程序

因为C语言语法格式的特殊性&#xff0c;还诞生了一个C语言乱码大赛&#xff0c;从1984年开始&#xff0c;一直办到现在。在它官网上能看到历年所有的参赛获奖的作品。 官网链接&#xff1a; https://www.ioccc.orghttps://github.com/ioccc-src/temp-test-ioccc 这个比赛的目…

美国政府发布新的国际网络空间和数字政策战略(上)

文章目录 前言一、战略内容介绍二、数字团结的含义三、如何建立数字团结前言 美国务院5月6日正式发布《美国国际网络空间和数字政策战略:迈向创新、安全和尊重权利的数字未来》,旨在指导国际社会参与技术外交并推动《美国国家安全战略》和《美国国家网络安全战略》。 美国务…

界面组件DevExpress Reporting中文教程 - 标记(可访问)PDF导出增强

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 可访问性支持在DevExpress这里仍然是一个高优先…