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

news2024/11/27 18:09:36

文章目录

  • 📋前言
  • 🎯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-column
          prop="id"
          label="id"
          width="80"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="name"
          label="姓名"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="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-pagination
          layout="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 实现联系人列表管理后台,基于这篇文章的内容学习来实现,敬请期待。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DataSpell第一次安装使用教程

官网&#xff1a; Download DataSpell: The IDE for Data Scientists (jetbrains.com) 双击.exe文件开始安装 安装过程就一直点击下一步就好&#xff0c;遇到方框需要勾选的全部勾上。 注意尽量别安装在C盘&#xff0c;我安装在了D盘。 获取jihuoma&#xff1a;(484条消息)…

MySql学习1:安装

前言 学习教程&#xff1a;黑马程序员 MySQL数据库入门到精通&#xff0c;从mysql安装到mysql高级、mysql优化全囊括 目前的打算是跟着教程学习基础部分&#xff0c;进阶和运维部分以后可能会学习。 安装 关于如何安装mysql可以跟着视频里的操作&#xff0c;但是对于我这种…

盘点一个AI你画我猜的小工具

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 寻声暗问弹者谁&#xff0c;琵琶声停欲语迟。 大家好&#xff0c;我是Python进阶者。 一、前言 前几天在【ChatGPT&AI破局俱乐部】知识星球发现了一…

【Python】Python系列教程-- Python3 字典(十四)

文章目录 前言创建空字典访问字典里的值修改字典删除字典元素字典键的特性字典内置函数&方法 前言 往期回顾&#xff1a; Python系列教程–Python3介绍&#xff08;一&#xff09;Python系列教程–Python3 环境搭建&#xff08;二&#xff09;Python系列教程–Python3 VS…

【Java】Java(四十七):单元测试

文章目录 1. 概述2. 特点3. 使用步骤4. 相关注解5. 疑惑: 有了main函数 为啥还要 单元测试6. 后记 1. 概述 JUnit是一个 Java 编程语言的单元测试工具。JUnit 是一个非常重要的测试工具 2. 特点 JUnit是一个开放源代码的测试工具。提供注解来识别测试方法。JUnit测试可以让…

在k8s平台部署个人博客(三)

先下载实战-在k8s平台部署个人博客-资源包 再K8s部署个人博客 实验步骤如下&#xff1a; [rootk8s-master]# kubectl create secret generic mysql-pass --from-literalpasswordYOUR_PASSWORD #把mysql.tar.gz和wordpress.tar.gz上传到K8s工作节点&#xff0c;手动解压即可…

java企业级信息系统开发学习笔记09 利用MyBatis实现CRUD操作

文章目录 一、学习目标利用MyBatis查询表记录利用MyBatis插入表记录利用MyBatis更新表记录利用MyBatis删除表记录 二、查询表记录1.打开mybatis项目&#xff08;一&#xff09;在映射器配置文件里引入结果映射元素&#xff08;二&#xff09;添加按姓名查询用户记录功能1、添加…

软考——下午题部分,例题一,二,三,六

例题一 11年上半年 病人&#xff0c;护理人员&#xff0c;医生 D 生命体征范围文件 日志文件 病历文件 治疗意见文件 14年上 E1 巴士司机,2 机械师,3 会计,4 主管,5 库存管理系统 D 巴士列表文件 维修记录文件 部件清单 人事档案 14年下 1 客户 2 供应商 D 销售订单表 库存…

基于simulink仿真弹跳球

一、前言 示例可视化了一个从地板上弹起的球。球在撞击地板时变形&#xff0c;保持球的体积恒定。变形是通过修改球的刻度场来实现的。 弹跳球实验有以下几个意义&#xff1a; 1. 研究物体的弹性&#xff1a;弹跳球实验可以帮助我们了解不同物体的弹性特性&#xff0c;包括弹性…

高校全奖PhD招生、大厂全职/实习招聘合集来了!快来拿offer!

本周&#xff0c;招聘小助手从「AI 求职」公众号中整理了来自 6 所高校和 6 家用人单位的「人工智能」相关全奖博士招生、算法实习等招聘信息。 分别来自新加坡国立大学、香港科技大学&#xff08;广州&#xff09;、华盛顿大学、字节跳动、小红书、京东、IDEA研究院等国内外知…

如何通过控制点或地物点生产地方坐标系的倾斜摄影三维模型数据?

如何通过控制点或地物点生产地方坐标系的倾斜摄影三维模型数据&#xff1f; 要生成地方坐标系的倾斜摄影三维模型数据&#xff0c;需要进行以下步骤&#xff1a; 1、收集影像数据 首先需要采集大量的航空影像和地面影像&#xff0c;以构建真实世界中的物体模型。这些影像可以…

Electron+Vue+Vite: 开发实践—初始化项目

运行系统:Apple M1 ,16 GB 开发工具:VSCode NodeJS:18.10 参考:https://github.com/electron-vite/electron-vite-vue.git 文章目录 创建项目构建项目客户端构建网页构建创建项目 npm create electron-vitecd electron-vite-tempsudo yarn installsudo yarn d

DDD与传统的OOA/D有什么区别?

DDD&#xff08;Domain-Driven Design&#xff09;与传统的OOA/D&#xff08;Object-Oriented Analysis and Design&#xff09;有以下几个不同点&#xff1a; 领域驱动设计注重建立一个通用语言&#xff0c;使得业务专家和技术人员之间能够沟通协作&#xff0c;在业务问题的解…

TrueNAS配置虚拟机网卡

TrueNAS支持运行虚拟机&#xff0c;但会出现虚拟机可以访问外网&#xff0c;却不能和主机的TrueNAS通讯。 这时&#xff0c;需要重新配置TrueNAS的网卡设置。 1. 原来的主机网卡配置 我的这台TrueNAS主机有两个以太网卡&#xff0c;目前使用的是enp4s0&#xff0c;IP地址192.1…

CPM-Bee本地部署的实战方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

从零开始学习JavaScript:轻松掌握编程语言的核心技能④

从零开始学习JavaScript&#xff1a;轻松掌握编程语言的核心技能④ 1. JavaScript 表单1.1 JavaScript 表单验证 2. JavaScript 保留关键字3. JavaScript this 关键字4. JavaScript let 和 const4.1 let4.2 const 5.JavaScript JSON6.JavaScript 异步编程7.JavaScript 代码规范…

4.协同工作与发布

目录 1 开发流程 2 人员分配情况 3 不同角色的权限 4 添加项目成员和体验成员 4.1 项目成员 4.1.1 添加 4.1.2 删除与修改权限 4.2 体验成员 4.2.1 添加 4.2.2 删除 5 发布上线 5.1 上传代码 5.2 提交审核 5.3 发布 6 推广 7 查看后台数据 1 …

留学生乱用ChatGPT真的太致命!被认定学术不诚信直接被退学?

01.ChatGPT留学生神器&#xff1f;作业论文全靠它&#xff1f; 近期留学圈内最火热的话题&#xff0c;肯定是关于ChatGPT。 “这个python作业我写不来&#xff0c;让ChatGPT帮我直接生成code就好了。” “论文英文的写不来&#xff0c;ChatGPT直接生成一篇essay&#xff0c;…

Linux - 进阶 使用 LAMP 搭建私有云存储 ( Nextcloud 搭建)

我们用到的私有云存储 >>> nextcloud (非常出名的一款 私有云搭建的应用响应程序 &#xff09; 预备工作 &#xff1a; # 关闭 selinux 及 防火墙 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld # 搭建 LAMP 环境 L &…

上市公司污染排放数据(2007-2022)

随着绿色金融的发展、环境信息披露政策制度的相继出台以及公众环保意识的增强&#xff0c;上市公司环境信息披露引起了学者、机构以及社会公众的广泛关注。本数据收集整理上市公司污染排放数据。 1、数据来源&#xff1a;自主整理 2、时间跨度&#xff1a;2007-2022年 3、区域…