当前位置: 首页 > news >正文

Vue3 + ElementPlus实战学习——模拟简单的联系人列表管理后台

文章目录

  • 📋前言
  • 🎯demo 介绍
  • 🎯功能分析
    • 🧩数据的展示与分页功能
    • 🧩编辑功能
    • 🧩删除功能
  • 🎯部分代码分析
  • 🎯完整代码
  • 📝最后


在这里插入图片描述

📋前言

这篇文章介绍一下基于 Vue3ElementPlus 的小 demo ,是一个模拟的联系人列表管理后台的,功能包括了数据的展示、编辑功能、删除功能以及列表分页功能。这篇文章是为了下一篇做基础和学习,因此列表的数据使用的是死数据。下一篇预告 Node.js + Vue3 + ElementPlus 实现联系人列表管理后台。


🎯demo 介绍

上面我也说到了,这个联系人列表管理后台的功能包括了数据的展示、编辑功能、删除功能以及列表分页功能。接下来我们来分析每个功能具体要做什么、以及如何实现。首先我们可以看到最终效果图如下。
在这里插入图片描述


🎯功能分析

接下来我们逐步分析这个 demo 要实现的功能。其中包括了数据的展示、编辑功能、删除功能以及列表分页功能。

🧩数据的展示与分页功能

在这里插入图片描述
首先项目运行后展示出的效果如上图,列表包括了 id 、姓名、电话以及相关操作,操作又包括了编辑功能和删除功能的按钮。

注意 id 是从小到大排列,其中数据中的 id 是没有排序的,如下图。
在这里插入图片描述
最后是数据列表的分页,这里用到的是 el-pagination 实现分页的功能,五条数据为一页。
在这里插入图片描述

🧩编辑功能

然后是编辑功能,通过点击编辑按钮,然后出现弹窗,对数据进行修改和保持,这里使用到了 el-dialogElMessage 实现窗口的出现、隐藏以及一些交互效果(消息框)。
在这里插入图片描述
交互效果包括了取消编辑、保存编辑的内容,通过 ElMessage 来实现交互后的消息框,效果如下图。
在这里插入图片描述

🧩删除功能

然后是编辑功能,通过点击删除按钮,然后出现是否确认删除的弹窗,这里使用到了 ElMessageBox 实现弹窗的出现以及确认、取消的交互效果。
在这里插入图片描述
点击确认后数据就会被删除了。然后通过 ElMessage 来实现交互后的消息框,比如删除成功的消息框。在这里插入图片描述


🎯部分代码分析

首先我们分析一下这个 demo 用的组件,有 el-buttonel-formel-cardel-dialogel-tableel-pagination 等等。

这个 demo 的 template 部分结构很简单,只包括了数据列表和弹窗通过 el-cardel-tableel-button 实现数据列表,el-dialogel-formel-button 实现弹窗的部分。

因为这个 demo 的数据是写死的了,没有后台数据以及 axios 获取 ,所以通过以下的方法实现数据列表的渲染。
在这里插入图片描述
其中默认数据如下。
在这里插入图片描述

弹窗部分的代码如下
在这里插入图片描述
然后还包括一些交互功能的代码,如弹窗的显示与隐藏。
在这里插入图片描述
然后就是显示弹窗以后,对应的交互功能,如取消(就是隐藏关闭掉弹窗)、保存的功能。

    // 保存联系人信息const saveContact = () => {const index = sortedContactList.value.findIndex((item) => item.id === editForm.value.id);if (index >= 0) {const oldItem = contactList.value.find((item) => item.id === editForm.value.id);contactList.value.splice(contactList.value.indexOf(oldItem), 1, {...oldItem,...editForm.value,});sortedContactList.value.splice(index, 1, {...oldItem,...editForm.value,});displayedData.value.splice(index - pageSize.value * (currentPage.value - 1),1,editForm.value);editFormVisible.value = false;ElMessage({message: "编辑成功!",grouping: true,type: "success",});}};

这里我来分析一下如何实现保存编辑内容的功能。首先这段代码的运行逻辑是在编辑联系人信息时,从 contactList 中找到对应的联系人数据项,并用 editForm 中的新数据来更新它,然后同步更新 sortedContactList 和 displayedData。最后,将编辑框关闭,并提示用户编辑成功。

具体逻辑如下。

  • 首先,通过 findIndex() 方法查找 sortedContactList 中是否存在 id 和 editForm 中的 id 相同的联系人数据项。(id 是联系人对象的唯一标识符)
  • 如果能够找到该联系人数据,就从 contactList 中找到对应的旧联系人数据项,并用新的 editForm 数据来更新它。同时,也更新 sortedContactList 中对应索引上的数据项。
  • 接着,根据当前页码和每页显示数量,还需要更新 displayedData 中对应位置的数据项。
  • 最后,将编辑框的 visible 属性设置为 false,关闭编辑框。并使用 ElMessage 组件显示一条“编辑成功”的成功提示信息。

在这里插入图片描述
当然,这个 demo 还有其他功能,这里就不过多描述了代码的具体功能了,详情还得是自己去编写了才能体验的到了,最后附上完整代码,供大家参考和学习


🎯完整代码

<template><div><!-- 编辑联系人dialog窗口 --><el-dialog title="编辑" v-model="editFormVisible" width="30%"><el-form :model="editForm" :rules="formRules" ref="editFormRef"><el-form-item label="姓名" prop="name"><el-input v-model="editForm.name"></el-input></el-form-item><el-form-item label="电话" prop="tel"><el-input v-model="editForm.tel"></el-input></el-form-item></el-form><template #footer><el-button @click="closeEditForm">取消</el-button><el-button type="primary" @click="saveContact">保存</el-button></template></el-dialog><el-card class="list-card"><el-table :data="displayedData" empty-text="暂无联系人"><el-table-columnprop="id"label="id"width="80"align="center"></el-table-column><el-table-columnprop="name"label="姓名"align="center"></el-table-column><el-table-columnprop="tel"label="电话"align="center"></el-table-column><el-table-column label="操作" width="150" align="center"><template #default="{ row }"><el-button size="small" @click="showEditForm(row)">编辑</el-button><el-button type="danger" size="small" @click="deleteContact(row)">删除</el-button></template></el-table-column></el-table><div class="pagination"><el-paginationlayout="prev, pager, next":total="contactList.length":page-size="pageSize"v-model:current-page="currentPage"@current-change="handleCurrentChange"/></div></el-card></div>
</template><script>
import { defineComponent, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
export default defineComponent({name: "ContactList",setup() {const contactList = ref([{ id: 3, name: "王五", tel: "15833333333" },{ id: 5, name: "钱七", tel: "17755555555" },{ id: 2, name: "李四", tel: "13922222222" },{ id: 1, name: "张三", tel: "13811111111" },{ id: 7, name: "周九", tel: "16577777777" },{ id: 6, name: "孙八", tel: "15066666666" },{ id: 10, name: "马二", tel: "13000000000" },{ id: 4, name: "赵六", tel: "18844444444" },{ id: 18, name: "高静", tel: "13888888888" },{ id: 17, name: "鲁阳", tel: "13777777777" },{ id: 16, name: "贾钢", tel: "13666666666" },{ id: 15, name: "金莉", tel: "13555555555" },{ id: 14, name: "胡伟", tel: "13444444444" },{ id: 13, name: "陈红", tel: "13333333333" },{ id: 12, name: "史琳", tel: "13222222222" },{ id: 11, name: "祖维", tel: "13111111111" },{ id: 9, name: "郑一", tel: "15999999999" },{ id: 8, name: "吴十", tel: "17688888888" },{ id: 19, name: "马超", tel: "13999999999" },{ id: 20, name: "周涛", tel: "14000000000" },]);const sortedContactList = ref([]);const displayedData = ref([]);const pageSize = ref(5);const currentPage = ref(1);const editFormVisible = ref(false);const editForm = ref({ id: "", name: "", tel: "" });const formRules = ref({name: [{ required: true, message: "请输入姓名", trigger: "blur" }],tel: [{required: true,message: "请输入电话号码",trigger: "blur",},{pattern: /^1[3456789]\d{9}/,message: "请输入有效的手机号码",trigger: "blur",},],});// 获取所有联系人列表const getContactList = () => {sortedContactList.value = contactList.value.slice().sort((a, b) => a.id - b.id);displayedData.value = sortedContactList.value.slice(0, pageSize.value);};// 显示编辑弹窗const showEditForm = (row) => {editFormVisible.value = true;editForm.value = Object.assign({}, row);};// 关闭编辑弹窗const closeEditForm = () => {editFormVisible.value = false;ElMessage({message: "已取消编辑。",grouping: true,type: "info",});};// 保存联系人信息const saveContact = () => {const index = sortedContactList.value.findIndex((item) => item.id === editForm.value.id);if (index >= 0) {const oldItem = contactList.value.find((item) => item.id === editForm.value.id);contactList.value.splice(contactList.value.indexOf(oldItem), 1, {...oldItem,...editForm.value,});sortedContactList.value.splice(index, 1, {...oldItem,...editForm.value,});displayedData.value.splice(index - pageSize.value * (currentPage.value - 1),1,editForm.value);editFormVisible.value = false;ElMessage({message: "编辑成功!",grouping: true,type: "success",});}};// 删除联系人const deleteContact = (row) => {const index = sortedContactList.value.findIndex((item) => item.id === row.id);ElMessageBox.confirm(`确定要删除联系人${row.name}`, "Warning", {confirmButtonText: "确认",cancelButtonText: "取消",type: "warning",}).then(() => {if (index >= 0) {const oldItem = contactList.value.find((item) => item.id === row.id);contactList.value.splice(contactList.value.indexOf(oldItem), 1);sortedContactList.value.splice(index, 1);displayedData.value.splice(index - pageSize.value * (currentPage.value - 1),1);ElMessage({message: "删除成功!",grouping: true,type: "success",});}});};// 处理页码改变事件const handleCurrentChange = (val) => {currentPage.value = val;const start = pageSize.value * (currentPage.value - 1);const end = pageSize.value * currentPage.value;displayedData.value = sortedContactList.value.slice(start, end);};// 初始化获取所有联系人列表getContactList();return {contactList,sortedContactList,displayedData,pageSize,currentPage,editFormVisible,editForm,formRules,getContactList,showEditForm,closeEditForm,saveContact,deleteContact,handleCurrentChange,};},
});
</script><style>
.pagination {margin-top: 20px;text-align: center;
}
</style>

📝最后

通过这篇文章的实战学习,学会实现的思路和基本的逻辑,为了下一篇内容做基础和学习,以及实现更多其他功能。下一篇预告 Node.js + Vue3 + ElementPlus 实现联系人列表管理后台,基于这篇文章的内容学习来实现,敬请期待。
在这里插入图片描述

相关文章:

Vue3 + ElementPlus实战学习——模拟简单的联系人列表管理后台

文章目录 &#x1f4cb;前言&#x1f3af;demo 介绍&#x1f3af;功能分析&#x1f9e9;数据的展示与分页功能&#x1f9e9;编辑功能&#x1f9e9;删除功能 &#x1f3af;部分代码分析&#x1f3af;完整代码&#x1f4dd;最后 &#x1f4cb;前言 这篇文章介绍一下基于 Vue3 和…...

【Go语言从入门到实战】并发篇

Go语言从入门到实战 — 并发篇 协程 Thread vs Groutine 相比之下&#xff0c;协程的栈大小就小很多了&#xff0c;创建起来也会更快&#xff0c;也更节省系统资源。 一个 goroutine 的栈&#xff0c;和操作系统线程一样&#xff0c;会保存其活跃或挂起的函数调用的本地变量…...

img标签请求 添加自定义header(二)

之前写过一篇关于img添加自定义请求头的处理方式&#xff08;点击这里&#xff09;&#xff0c;那么本篇我们来看另外几种实现方法。 自定义指令 以Vue为例&#xff0c;我们可以定义一个全局指令&#xff0c;对img标签进行一些处理。 <template><img :src"src…...

Set和weakSet Map和WeakMap

Set和weakSet的用法和区别 1.Set 和weakSet 它是类似于数组&#xff0c;且成员值都是唯一的&#xff0c; 2.Set有 add has delete clear size keys values forEach entries 3.weakSet 有add has delete 4.WeakSet中只能存放对象类型&#xff0c;不能存放基本类型 5.WeakSet它是…...

Qt基础之三十六:异常处理

本文将介绍如何在Qt中使用try...catch和调试dump文件来处理异常。 Qt版本5.12.6 一.使用try...catch 一段简单的捕获异常的代码,新建一个控制台工程,pro文件不用修改 #include <QCoreApplication> #include <QDebug>int main(int argc, char *argv[]) {QCoreA…...

【HMS Core】【ML Kit】活体检测FAQ合集

【问题描述1】 使用示例代码集成活体检测SDK时&#xff0c;报错state code -7001 【解决方案】 使用示例代码前请详细阅读示例工程中的“README”文件。您需要完成以下操作后才可以运行示例代码。 在AppGallery Connect网站下载自己应用的“agconnect-services.json”文件&a…...

ChatGPT:使用OpenAI创建自己的AI网站,使用 flask web框架快速搭建网站主体

使用OpenAI创建自己的AI网站 如果你还是一个OpenAI的小白&#xff0c;有OpenAI的账号&#xff0c;但想调用OpenAI的API搞一些有意思的事&#xff0c;那么这一系列的教程将仔细的为你讲解如何使用OpenAI的API制作属于自己的AI网站。 使用 flask web框架快速搭建网站主体 之前…...

后端(一):Tomcat

我们之前的前端是被我们一笔带过的&#xff0c;那不是我们要讲的重点&#xff0c;而这里的后端则是重点。本章先来认识认识后端的基础。 Tomcat 是什么 我们先来聊聊什么叫做tomcat&#xff0c;我们熟悉的那个是汤姆猫&#xff1a; 这和我们Java世界中的Tomcat 不是同一只猫&…...

华为OD机试之最小调整顺序次数、特异性双端队列(Java源码)

最小调整顺序次数、特异性双端队列 题目描述 有一个特异性的双端队列&#xff0c;该队列可以从头部或尾部添加数据&#xff0c;但是只能从头部移出数据。 小A依次执行2n个指令往队列中添加数据和移出数据。其中n个指令是添加数据&#xff08;可能从头部添加、也可能从尾部添加…...

2023年武汉住建厅七大员怎么报名?报名流程?精准题库一次过??

2023年武汉住建厅七大员怎么报名?报名流程&#xff1f;精准题库一次过&#xff1f;&#xff1f; 2023年武汉住建厅七大员是指施工员、质量员、资料员、材料员、机械员、标准员、劳务员&#xff0c;报的最多的可能就是施工员&#xff0c;质量员和资料员 报名流程&#xff1a; 1…...

Rust每日一练(Leetday0014) 组合总和II、缺失正数、接雨水

目录 40. 组合总和 II Combination Sum II &#x1f31f;&#x1f31f; 41. 缺失的第一个正数 First Missing Positive &#x1f31f;&#x1f31f;&#x1f31f; 42. 接雨水 Trapping Rain Water &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题…...

EnjoyVIID部署

1、下载 git clone https://gitee.com/tsingeye/EnjoyVIID.git 2、导入数据库 创建表enjoyviid 导入数据库(修改数据库文件里的编码) EnjoyVIID/sql/tsingeye-viid.sql 3、修改配置 vim EnjoyVIID/tsingeye-admin/src/main/resources/application-dev.yml 修改数据库连接、re…...

用Python解决爱因斯坦的数学问题

1 问题 有一条阶梯&#xff0c;若每步跨2阶&#xff0c;则剩最后一阶&#xff0c;若每步跨3阶&#xff0c;则最后剩2阶&#xff0c;若每步跨5阶&#xff0c;则最后剩4阶&#xff0c;若每步跨6阶&#xff0c;则最后剩5阶&#xff0c;只有每次跨7阶&#xff0c;最后才刚好不剩&am…...

ChatGPT提示词攻略之基本原则

下面是调用openai的completion接口的函数。但在本文中并不是重点。了解一下就好。 import openai import osfrom dotenv import load_dotenv, find_dotenv _ load_dotenv(find_dotenv())openai.api_key os.getenv(OPENAI_API_KEY)def get_completion(prompt, model"gp…...

抖音seo源码如何开发部署?

前言&#xff1a;抖音seo源码&#xff0c;抖音矩阵系统源码搭建&#xff0c;抖音矩阵同步分发。抖音seo源码部署是需要对接到这些正规接口再来做开发的&#xff0c;目前账号矩阵程序开发的功能&#xff0c;围绕一键管理多个账号&#xff0c;做到定时投放&#xff0c;关键词自动…...

Java中常见锁的分类及概念分析

基于线程对同一把锁的获取情况分类 可重入锁 同一个线程可以多次获取锁 每次获取锁&#xff0c;锁的计数器加1&#xff0c;每次释放锁锁的计数器减1 锁的计数器归零&#xff0c;锁完全释放 Java中提供的synchronized&#xff0c;ReentrantLock&#xff0c;ReentrantReadWriteL…...

ConcurrentLinkedQueue的源码解析(基于JDK1.8)

ConcurrentLinkedQueue的源码解析&#xff08;基于JDK1.8&#xff09; ConcurrentLinkedQueue是Java集合框架中的一种线程安全的队列&#xff0c;它是通过CAS&#xff08;Compare and Swap&#xff09;算法实现的并发队列。在并发场景下&#xff0c;ConcurrentLinkedQueue能够…...

低资源方面级情感分析研究综述

文章目录 前言1. 引言2. 问题定义、数据集和评价指标2.1 问题定义2.2 任务定义2.3 常用数据集 3. 方面级情感分析的方法3.1 **方面词抽取**3.1.1 基于无监督学习的方法3.1.1.1 基于规则的方面词抽取3.1.1.2 基于统计的方面词抽取 3.1.2 基于有监督浅层模型的方法3.1.3 基于有监…...

将 PDF 压缩到 1 MB 或更小的 5 个工具

鉴于工作和生活中PDF文件的频繁传输&#xff0c;压缩文件大小成为PDF文件必不可少的一步&#xff0c;尤其是对于包含大量高清图片的文件。压缩不仅使您的文件兼容发送&#xff0c;还有助于存储优化。这意味着您将获得更多数据空间&#xff0c;适用于本地设备和云端。 想要将 …...

CSMA/CD协议之计算最短帧长问题

文章目录 前言CSMA/CD协议计算最短帧长 前言 本篇博客主要论述了如何计算 CSMA/CD 协议下的网络帧长问题&#xff0c;从概念入手&#xff0c;结合例题进行详细的分析。 CSMA/CD协议 概念&#xff1a; ① 载波监听多点接入/碰撞检测 ② 半双工通信 ③ 先听后发、边听边发、冲…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...