Vue3的CRUD模版(附Demo)

embedded/2024/10/15 16:02:38/

目录

  • 前言
  • 模版

前言

用惯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.ppmy.cn/embedded/39992.html

相关文章

基于微信小程序的图书馆预约系统的设计与实现

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

vue3配置基础路径

我们在部署项目的时候&#xff0c;有时项目很多时&#xff0c;可能并不是直接部署到根目录下&#xff0c;那么就需要给项目配置一个公共目录。例如&#xff1a;www.iotzzh.com/zh-admin&#xff0c;用这个地址去访问项目而不是直接使用www.iotzzh.com。 那么在vue3中需要改两处…

python视频转码脚本

今天有一个临时的需求&#xff0c;就是需要将一个wmv的初步转码成mp4的格式。找了一圈&#xff0c;免费的工具少&#xff0c;即使有免费的工具&#xff0c;在功能上也是有所限制&#xff0c;或者会给你塞广告或者附带安装其它流氓小游戏或者杀毒程序。 我并非不支持正版&#…

递归求fabonacci数列 pta

斐波那契数列&#xff08;Fibonacci sequence&#xff09;是一个经典的数列&#xff0c;它由以下递归关系定义&#xff1a; [ F(n) F(n-1) F(n-2) ] 其中&#xff0c;( F(0) 0 ) 和 ( F(1) 1 )。 在编程中&#xff0c;递归是一种实现斐波那契数列的直观方法。以下是使用递…

Docker搭建ctfd平台

安装docker和docker-compose &#xff08;1&#xff09;安装docker&#xff1a; curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun&#xff08;2&#xff09;安装 Docker Compose&#xff1a; yum install docker-compose安装失败参考下面文章 https:/…

matlab人脸识别

在MATLAB中实现人脸识别通常涉及到图像处理、特征提取和分类器的使用。下面是一个简化的MATLAB人脸识别代码的概述&#xff0c;使用了PCA&#xff08;主成分分析&#xff09;作为特征提取方法&#xff0c;以及简单的分类器&#xff08;如最近邻分类器&#xff09;进行分类。请注…

Android面试题之kotlin热流和channel

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点 于冷流不同&#xff0c;在垃圾回收之前&#xff0c;flow里的值都是存在内存之中&#xff0c;并且处于活跃状态 StateFlow StateFlow是一个状态容…

Django性能之道:缓存应用与优化实战

title: Django性能之道&#xff1a;缓存应用与优化实战 date: 2024/5/11 18:34:22 updated: 2024/5/11 18:34:22 categories: 后端开发 tags: 缓存系统Redis优点Memcached优缺点Django缓存数据库优化性能监控安全实践 引言 在当今的互联网时代&#xff0c;用户对网站和应用…