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

Vue实战【封装一个简单的列表组件,实现增删改查】

文章目录

  • 🌟前言
  • 🌟table组件封装
  • 🌟父组件(展示表格的页面)
  • 🌟控制台查看父子组件通信是否成功
  • 🌟Vue2父子组件传递参数
  • 🌟写在最后
  • 🌟JSON包里写函数,关注博主不迷路

🌟前言

大家好,上一期的Vue实战都阅读了吗?上一期主要是对Vuex的一个基本操作,通过Vuex我们可以实现全局的状态(数据)共享,以便与我们更好的实现一些需求。
不知道大家在日常工作当中是否被频繁的列表增删改查困扰,功能很简单但确实是非常繁琐的一项工作;今天这一期呢我会从Vue2父子组件如何传值并结合Element来封装一个简单的列表组件;一次封装,多次复用。

🌟table组件封装

在你的component目录下创建一个Table.vue:

<template><el-card class="box-card" style="width: 100%;height: 100%"><div class="btnBox"><el-button v-for="(item,index) in tableOperation" :key="index" :type="item.type" size="small" @[eventName]="handleClick(item.fun, multipleSelection)">{{ item.label }}</el-button></div><el-tablestyle="margin-bottom: 20px":data="tableData"size="small"row-class-name="row"cell-class-name="column":highlight-current-row="true"fit@selection-change="handleSelectionChange"><!--这是是为了将表格设置成带有选择框的表格--><el-table-columntype="selection"width="55"/><el-table-columnv-for="(item, index) in tableLabel":key="index"align="center":prop="item.prop":width="item.width":label="item.label"/></el-table><div class="block" style="text-align: end"><el-paginationbackground:current-page="1":page-sizes="[10, 20, 30, 40]":page-size="10"layout="total, sizes, prev, pager, next, jumper":total="tableData.length"@size-change="handleSizeChange"@current-change="handleCurrentChange"/></div></el-card></template><script>
export default {name: 'Table',// 因为是子组件,要接受父组件传递的数据,所以这里我们定义propsprops: {tableData: { // 父组件传递过来的表格数据type: Array,default: () => {return []}},tableLabel: { // 父组件传递过来的表头数据type: Array,default: () => {return []}},tableOperation: { // 父组件传递过来的操作按钮数据type: Array,default: () => {return []}}},data() {return {eventName: 'click',  // 点击按钮绑定的方法,这样写法也可以去绑定一些其他的比如change等方法multipleSelection: [] // 这个数组用来保存被选择行的数据,顺序是按照你勾选的顺序来排序的}},methods: {// @selection-change方法可以监听到表格里哪一行被选中,类型是数组;// 然后我们将它赋值给定义好的 multipleSelection handleSelectionChange(val) {this.multipleSelection = val},// 动态绑定操作按钮的点击事件(按钮是父组件传递过来循环出来的,所以我们给按钮定义一个方法)// 接收两个参数,一个是fun(string类型),一个是row(array类型,也就是我们选中行的数据)// 这里的某个按钮时传递的参数// 比如我点击的是编辑,那这时的fun就是 'edit',执行的方法就是下边的this.edit(row)handleClick(fun,row) {this[fun](row)},edit(row) {if (!row.length) {this.$message.error('请勾选数据后操作')return false} else if (row.length > 2) {this.$message.error('当前仅支持单条数据操作')return false} else {console.log('子组件点击编辑,触发父组件方法;并传递数据', row)// 通过$meit通知父组件propClick方法,并传递两个参数:'edit'和rowthis.$emit('propClick', 'edit', row)}},look(row) {if (!row.length) {this.$message.error('请勾选数据后操作')return false} else if (row.length > 2) {this.$message.error('当前仅支持单条数据操作')return false} else {console.log('子组件点击查看,触发父组件方法;并传递数据', row)// 通过$meit通知父组件propClick方法,并传递两个参数:'edit'和rowthis.$emit('propClick', 'look', row)}},delete(row) {if (!row.length) {this.$message.error('请勾选数据后操作')return false} else if (row.length > 2) {this.$message.error('当前仅支持单条数据操作')return false} else {console.log('子组件点击删除,触发父组件方法;并传递数据', row)// 通过$meit通知父组件propClick方法,并传递两个参数:'edit'和rowthis.$emit('propClick', 'del', row)}},handleSizeChange(val) {console.log(`每页 ${val}`)},handleCurrentChange(val) {console.log(`当前页: ${val}`)}}
}
</script><style scoped></style>

table组件封装好了,就可以在父组件里使用啦。

🌟父组件(展示表格的页面)

创建一个父组件(也就是你的页面),我这里起名index.vue大家可以随意;


<template><div v-loading="tableLoading" class="dashboard-container"><!--子组件位置--><!--自定义table-data,table-label,table-operation三个属性,分别传递我们需要的数据--><!--自定义@propClick方法,用来接收子组件的通知并执行定义的btnClick方法--><myTable:table-data="tableData" :table-label="tableLabel":table-operation="tableOperation"@propClick="btnClick" /></div>
</template><script>
import { mapGetters } from 'vuex'
// 根据你的table组件引入到父组件里
import myTable from '@/components/Table/table'
export default {name: 'Dashboard',// 并在父组件的compoments里边注册components: {myTable},computed: {...mapGetters(['name'])},// eslint-disable-next-line vue/order-in-componentsdata() {return {tableLoading: true,// 子组件的表格数据tableData: [{ id: 1, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 2, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 3, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 4, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 5, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 6, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 7, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 8, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 9, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 10, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 11, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 },{ id: 12, date: '2018-07-24', sales: 23.34, sale: 137597.76, const: 102203.71, profit: 35394.05 }],// 子组件的表头数据tableLabel: [{ label: 'ID', width: '40', prop: 'id' },{ label: '日期', width: '', prop: 'date' },{ label: '销售量', width: '', prop: 'sales' },{ label: '销售额', width: '', prop: 'sale' },{ label: '成本', width: '', prop: 'const' },{ label: '利润', width: '', prop: 'profit' }],// 子组件的操作按钮tableOperation: [{ label: '编辑', fun: 'edit', type: 'primary' },{ label: '查看', fun: 'look', type: 'success' },{ label: '删除', fun: 'delete', type: 'danger' }]}},mounted() {setTimeout(() => {this.tableLoading = falsethis.$message.success('数据加载成功')}, 1000)},methods: {// 当父组件接收到了子组件this.$emit的通知后就会执行这个方法来接收子组件点击传递过来的数据btnClick(fun, row) {if (fun === 'edit') {console.log('子组件点击了编辑,父组件收到子组件传递的数据', row)} else if (fun === 'look') {console.log('子组件点击了查看,父组件收到子组件传递的数据', row)} else if (fun === 'del') {console.log('子组件点击了删除,父组件收到子组件传递的数据', row)}}}
}
</script><style lang="scss" scoped>
.dashboard {&-container {/*width: 100%;*/margin: 30px;height: 88vh;}&-text {font-size: 30px;line-height: 46px;}
}
</style>

🌟控制台查看父子组件通信是否成功

列表增删改查

🌟Vue2父子组件传递参数

接下来我们来复习一下父子组件传递参数的方法吧

父组件向子组件传递数据:

父组件通过 props 给子组件下发数据

  • 在父组件内为子组件添加自定义属性,例如我上边的table-data,table-label,table-operation三个属性,并为其绑定数据;如果是动态绑定就需要加上 ,反则不用加。
  • 子组件内通过定义props来接受数据;并且有以下几个参数配置;
属性说明
type原生构造器参数的类型
defaultany参数的默认值,数组/对象的默认值应当由一个工厂函数返回
requiredtrue/false参数是否必传
validatorfunction自定义验证函数
Vue.component('example', {props: {// 基础类型检测 (`null` 指允许任何类型)propA: Number,// 可能是多种类型propB: [String, Number],// 必传且是字符串propC: {type: String,required: true},// 数值且有默认值propD: {type: Number,default: 100},// 数组/对象的默认值应当由一个工厂函数返回propE: {type: Object,default: function () {return { message: 'hello' }}},// 自定义验证函数propF: {validator: function (value) {return value > 10}},propG: {validator: function (value) {// 这个值必须匹配下列字符串中的一个return ['success', 'warning', 'danger'].indexOf(value) !== -1}}}
})

子组件向父组件传递数据:

子组件通过事件给父组件发送消息

每个 Vue 实例都实现了事件接口,即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName, optionalPayload) 触发事件

1. 主要方法在父组件里。
2. 在父组件里添加自定义事件,自定义事件触发执行主要方法。
3. 在子组件里写一个通知方法( this.$emit(‘自定义事件’,参数) )用来告诉父组件执行自定义事件。
4. 在需要触发这个事件的元素上添加触发事件(例:@click=“子组件里的通知方法”)

<!-- 子组件 -->
<template><el-card class="box-card" style="width: 100%;height: 100%"><div class="btnBox"><el-buttonv-for="(item,index) in tableOperation":key="index":type="item.type"size="small"@click="handleClick(item.fun, multipleSelection)">{{ item.label }}</el-button></div></el-card></template><script>
export default {name: 'Table',methods: {add(row) {console.log('子组件点击新增,触发父组件里的自定义事件-propClick')this.$emit('propClick', 'add')}}
}
</script><style scoped></style>
<!-- 父组件 -->
<template><div v-loading="tableLoading" class="dashboard-container"><myTable @propClick="btnClick" /></div>
</template><script>
import myTable from '@/components/Table/table'
export default {name: 'Dashboard',components: {myTable},methods: {//自定义事件-propClick触发该方法, 接收子组件点击按钮数据btnClick(fun, row) {if (fun === 'edit') {console.log('子组件点击了编辑,父组件收到子组件传递的数据', row)// 这里就可以去写我们需要调用的接口呀,数据处理逻辑呀等等} else if (fun === 'look') {console.log('子组件点击了查看,父组件收到子组件传递的数据', row)// 这里就可以去写我们需要调用的接口呀,数据处理逻辑呀等等} else if (fun === 'del') {console.log('子组件点击了删除,父组件收到子组件传递的数据', row)// 这里就可以去写我们需要调用的接口呀,数据处理逻辑呀等等}}}
}
</script>

🌟写在最后

这篇文章通过父子组件通信并结合Element封装了一个简单的增删改查列表组件,你是否学会了呢?很多复杂的功能都是通过基础知识举一反三得来的,小伙伴一定记的尝试哦。后续会为小伙伴们持续更新Vue的一些实战小魔法!各位小伙伴让我们 let’s be prepared at all times!

🌟JSON包里写函数,关注博主不迷路

✨原创不易,还希望各位大佬支持一下!
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!

相关文章:

Vue实战【封装一个简单的列表组件,实现增删改查】

文章目录&#x1f31f;前言&#x1f31f;table组件封装&#x1f31f;父组件&#xff08;展示表格的页面&#xff09;&#x1f31f;控制台查看父子组件通信是否成功&#x1f31f;Vue2父子组件传递参数&#x1f31f;写在最后&#x1f31f;JSON包里写函数&#xff0c;关注博主不迷…...

微前端(无界)

前言&#xff1a;微前端已经是一个非常成熟的领域了&#xff0c;但开发者不管采用哪个现有方案&#xff0c;在适配成本、样式隔离、运行性能、页面白屏、子应用通信、子应用保活、多应用激活、vite 框架支持、应用共享等用户核心诉求都或存在问题&#xff0c;或无法提供支持。本…...

强烈推荐:0基础入门网安必备《网络安全知识图谱》

蚁景网安学院一直专注于网安实战技能培养&#xff0c;提供全方位的网安安全学习解决方案。我们集聚专业网安技术大佬资源&#xff0c;倾力打造了这本更全面更系统的“网络安全知识图谱”&#xff0c;让大家在网络安全学习路上不迷茫。 在这份网安技能地图册里&#xff0c;我们对…...

网络技术与应用概论(上)——“计算机网络”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰的内容依旧是计算机网络的一些知识点噢&#xff0c;下面&#xff0c;让我们进入计算机网络的世界吧 网络内涵 网络特征 网络定义 互联网发展过程 从ARPA网络到Internet 从低速互联网到高速互联网 从数据结构到统一网…...

JAVASE/封装、继承、多态

博客制作不易&#xff0c;欢迎各位点赞&#x1f44d;收藏⭐关注前言在学习面向对象编程语言时&#xff0c;封装、继承、多态则是我们必须学习和使用的三大特征。本文通过举例&#xff0c;说明了该三大特征的基本权限特点。一、访问限定符范围private默认权限protectedpublic同一…...

SpringBoot ElasticSearch 【SpringBoot系列16】

SpringCloud 大型系列课程正在制作中&#xff0c;欢迎大家关注与提意见。 程序员每天的CV 与 板砖&#xff0c;也要知其所以然&#xff0c;本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCloud 微服务系列项目开发 elasticsearch是一款非常强大的开源搜索引擎&a…...

Virtual box磁盘大小调整操作

Virtual box磁盘大小调整操作环境说明思路操作1、挂载要压缩的硬盘到 ~/data2、填充 0 文件3、删除 全是0空文件4、虚拟机关机5、在windows环境下用VBoxManage.exe 进行压缩硬盘加大环境说明 主机 windows 虚拟机 ubuntu 分配了 80G 的硬盘&#xff0c;现在已经占用 80 G 了。…...

MySQL注入秘籍【上篇】

MySQL注入秘籍【上篇】1.数据库敏感信息常用语句2.联合(UNION)查询注入3.报错注入原理常见报错注入函数1.数据库敏感信息常用语句 获取数据库版本信息 select version(); select innodb_version;获取当前用户 select user();获取当前数据库 select database()&#xff1b;数…...

简单三步解决动态规划难题,记好这三步,动态规划就不难

目录一、简单的一维DP剑指 Offer 10- I. 斐波那契数列1、三板斧解决问题2、优雅的解决问题剑指 Offer 63 股票的最大利润1、三板斧解决问题2、优雅的解决问题二、进阶的二维DP剑指offer47 礼物的最大价值1、三板斧解决问题2、优雅的解决问题编辑距离1、三板斧解决问题2、优雅的…...

算法进阶指南打卡

文章目录 基本算法 位运算递推与递归前缀和与差分二分排序倍增贪心总结与练习基本数据结构 栈队列链表与邻接表Hash字符串Tire二叉堆总结与练习搜索 树与图的遍历深度优先搜索剪枝迭代加深广度优先搜索广度变形A*IDA*总结与练习数学知识 质数约数同余矩阵乘法高斯消元与线性空…...

Chapter6.2:其他根轨迹及综合实例分析

该系列博客主要讲述Matlab软件在自动控制方面的应用&#xff0c;如无自动控制理论基础&#xff0c;请先学习自动控制系列博文&#xff0c;该系列博客不再详细讲解自动控制理论知识。 自动控制理论基础相关链接&#xff1a;https://blog.csdn.net/qq_39032096/category_10287468…...

3. 无重复字符的最长子串——滑动窗口

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。 示例 2: 输入: s "bbbbb" 输出: 1 解释: 因为无…...

ChatGPT研究分享:机器第一次开始理解人类世界

0、为什么会对ChatGPT感兴趣一开始&#xff0c;我对ChatGPT是没什么关注的&#xff0c;无非就是有更大的数据集&#xff0c;完成了更大规模的计算&#xff0c;所以能够回答更多的问题。但后来了解到几个案例&#xff0c;开始觉得这个事情并不简单。我先分别列举出来&#xff0c…...

可换皮肤的Qt登录界面

⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支持一下呗。👍⭐️❤️ 可换皮肤的Qt登录界面 QSS的学习笔记 快…...

Spring的常见问题汇总

一、bean实例化1、构造方法底层是无参构造方法来new的对象。2、静态工厂实例化Bean实质上就是&#xff1a;创建一个静态工厂类&#xff0c;然后调用静态工厂类的静态方法&#xff0c;来创建对象。3、实例工厂与FactoryBean实质上就是&#xff1a;创建一个工厂类&#xff0c;工厂…...

yolov8训练筷子点数数据集

序言 yolov8发布这么久了&#xff0c;一直没有机会尝试一下&#xff0c;今天用之前自己制作的筷子点数数据集进行训练&#xff0c;并且记录一下使用过程以及一些常见的操作方式&#xff0c;供以后翻阅。 一、环境准备 yolov8的训练相对于之前的yolov5简单了很多&#xff0c;…...

使用 Python 从点云生成 3D 网格

从点云生成 3D 网格的最快方法 已经用 Python 编写了几个实现来从点云中获取网格。它们中的大多数的问题在于它们意味着设置许多难以调整的参数&#xff0c;尤其是在不是 3D 数据处理专家的情况下。在这个简短的指南中&#xff0c;我想展示从点云生成网格的最快和最简单的过程。…...

vue使用split()将字符串分割数组join()将数组转字符串reverse()将数组反转

1.split() 将字符串切割成数组 const str Hello Vue2 Vue3 console.log(str.split()) console.log(str.split()) console.log(str.split( )) console.log(str.split( , 2)) console.log(str.split( , 6))输出如下 1.split()不传参数默认整个字符串作为数组的一个元素&#xf…...

队列实现及leetcode相关OJ题

上一篇写的是栈这一篇分享队列实现及其与队列相关OJ题 文章目录一、队列概念及实现二、队列源码三、leetcode相关OJ一、队列概念及实现 1、队列概念 队列同栈一样也是一种特殊的数据结构&#xff0c;遵循先进先出的原则&#xff0c;例如&#xff1a;想象在独木桥上走着的人&am…...

【Log4j2远程命令执行复现CVE-2021-12-09】

目录 一、前言 二、漏洞环境构建 三、复现过程 一、前言 Log4j2是基于log4j这个java日志处理组件进行二次开发和改进而来的。也是目前最常用的日志框架之一&#xff0c;在之前的博客中&#xff08;http://t.csdn.cn/z9um4&#xff09;我们阐述了漏洞的原理和大致的利用方…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...