三种简洁易行的方法解决基于Vue.js的组件通信

news2024/9/20 18:50:21

  在总结Vue组件化编程的数据通信方面,看了网上的很多资料,都是讲父子组件的数据交互也就是参数传递,在组件的通信方面分几种情况,比如父子组件、非父子的兄弟组件、非父子的其他组件等等,这样看来,基于Vue.js的组件通讯非常繁琐。

  可是我们在C/S下的组件通信并没有这些麻烦,通常情况下,我们怎样设计组件通信?

  在组件上声明事件,可以是截获系统事件的,也可以是自定义事件,在这个事件中,我们就可以对外进行数据通信。

  沿着这个思路,就可以解决Vue组件化编程的组件通信,很简单了。

  另外,在Windows中的消息队列中,我们也可以通过捕获事件的方式来得到组件的操作和数据,也同样可以实现Vue组件化编程的组件通信。

  最简单的,当然是组件中的数据直接对外进行数据绑定,这样也就可以实现组件通信了。

  所以总结基于Vue.js的组件通信,比较简单易用的三种方式:通过数据绑定与数据监听、通过组件的自定义函数(事件)、通过事件捕获

  下面针对这三种情况分别举例说明。

  用于演示的基本数据结构:

personList:[
    {name:'小明',score:97},
    {name:'小丽',score:88},
	{name:'小英',score:95},
]

  假设现在需要计算score的总和,并且总分也要随着这些分数值的变化而变化。

  1、通过数据绑定与数据监听

  首先,在Vue实例的data中定义用于计算总和的数据项total以及personList,再定义组件放置姓名和分数(input输入框),然后组件的数据项与personList绑定,最后监听personList数据变化就可以得到总和,并且每个input框的分数变化后总分也随之变化。

  完整网页代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue.js的组件化编程:组件通信</title>
		<script src="./js/vue2.js"></script>
	</head>
	<body>
		<div id="app">
			<h2>人员表</h2>
			<my-person v-for="(p,index) in personList" :key="index" :my-person="personList[index]"></my-person>
			<p>总分:{{ total }}</p>
		</div>
		<script type="text/javascript">
			Vue.component("myPerson",{
				props:['myPerson'],
				template:`<div>
						姓名:{{ myPerson.name }}
						分数:<input type="number" v-model="myPerson.score"/>
					</div>`,
			});
			var vm=new Vue({
				el:"#app",
				data:{
					total:0,
					personList:[
						{name:'小明',score:97},
						{name:'小丽',score:88},
						{name:'小英',score:95},
					]
				},
				methods:{
					ScoreChange(){
						this.total = this.personList.reduce((prev, curr) => {
							return parseInt(prev) + parseInt(curr.score)
						}, 0)
					}
				},
				watch:{
					personList:{
						handler:'ScoreChange',
						deep:true,//深度监听
						immediate:true,//有初始值
            		}
				}
			});
		</script>
	</body>
</html>

  显示输出:

  2、通过组件的自定义函数(事件)

  直接叙述就是在组件的响应事件中调用其他组件的数据或者方法,不用区分父子关系。

  完整的代码示例:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue.js的组件化编程:组件通信</title>
		<script src="./js/vue2.js"></script>
	</head>
	<body>
		<div id="app">
			<h2>人员表</h2>
			<my-person :my-name="'小明'" :my-score="'99'"  ref="S1"></my-person>
			<my-person :my-name="'小丽'" :my-score="'87'"  ref="S2"></my-person>
			<p>总分:{{total}}</p>
		</div>
		<script type="text/javascript">
			Vue.component("myPerson",{
				props:['myName','myScore'],
				data(){
					return {
							person:{
								name:"",
								score:0
							}
					}
				},
				mounted() {
					this.person.name=this.myName;
					this.person.score=this.myScore;
				},
				template:`<div>
						姓名:{{ person.name }}
						分数:<input type="number" v-model="person.score" @input="dataChange()"/>
					</div>`,
				methods:{
					dataChange(){
						this.$parent.total=parseInt(this.$parent.$refs.S1.person.score) + parseInt(this.$parent.$refs.S2.person.score);
					}
				}
			});
			var vm=new Vue({
				el:"#app",
				data:{
					total:0
				}
			});
		</script>
	</body>
</html>

  输出结果:

  说明:

  ⑴ 数据绑定可以在created或者mounted中进行;

  ⑵ 绑定的时候不能少写this,否则会提示找不到数据项;

  ⑶ 关键在事件中的处理,即this.$parent.$refs包含了组件数据,所以在放置组件的时候要写ref属性值(不能重复)。

  3、通过事件捕获

  直接叙述就是声明另外一Vue实例进行事件挂载与事件捕获,就是组件的事件在Vue实例上进行注册,在另外组件上需要处理的时候就捕获这个事件即可。

  完整的代码示例:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue.js的组件化编程:组件通信</title>
		<script src="./js/vue2.js"></script>
	</head>
	<body>
		<div id="app">
			<h2>人员表</h2>
			<my-person :my-name="'小明'" :my-score="'99'"  ref="S1"></my-person>
			<my-person :my-name="'小丽'" :my-score="'87'"  ref="S2"></my-person>
			<my-total></my-total>
		</div>
		<script type="text/javascript">
			eventBus=new Vue();
			Vue.component("myPerson",{
				props:['myName','myScore'],
				data(){
					return {
							person:{
								name:"",
								score:0
							}
					}
				},
				mounted() {
					this.person.name=this.myName;
					this.person.score=this.myScore;					
				},
				template:`<div>
						姓名:{{ person.name }}
						分数:<input type="number" v-model="person.score" @input="myDataChange()"/>
					</div>`,
				methods:{
					myDataChange(){
						eventBus.$emit('DataChange',this.person);						
					}
				}
			});

			Vue.component("myTotal",{
				data(){
					return {
						total:0,
						personList:[]
					}
				},
				mounted() {
					eventBus.$on('DataChange',(p)=>{
						this.total=0;
						if( !this.personList.find(obj=>obj.name==p.name) ){
							this.personList.push(p);
						}
						this.personList.forEach(element => {
							this.total+=parseInt(element.score);
						});							
					})
				},
				template:`<div>总数:{{ total }}</div>`
			});
			var vm=new Vue({
				el:"#app"
			});
		</script>
	</body>
</html>

  结果输出:

   说明:

  ⑴ 需要声明另外一个Vue实例,名称可以根据自己需要设定;

  ⑵  组件的数据绑定可以在created或者mounted中进行;

  ⑶ 组件的事件触发eventBus.$emit('DataChange',this.person),DataChange可以被其他组件进行捕获处理;

  ⑷ 其他组件捕获事件

eventBus.$on('DataChange',(p)=>{
    //p是传递过来的参数
    //......
})

  原来Vue组件的数据通信这么简单!

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

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

相关文章

STC15系列单片机EEPROM读写示例

STC15系列单片机EEPROM读写示例&#x1f33c;STC15手册有关EEPROM描述 &#x1f33e;STC15系列单片机内部集成了大容量的EEPROM&#xff0c;其与程序空间是分开的。利用ISP/IAP技术可将内部DataFlash当EEPROM&#xff0c;擦写次数在10万次以上。EEPROM可分为若干个扇区&#xf…

Android 蓝牙开发——蓝牙协议配置(七)

蓝牙主要分为两种模式&#xff0c;一种是媒体输出&#xff08;Source&#xff09;端&#xff0c;一种是媒体输入&#xff08;Sink&#xff09;端。也可以理解为服务端&#xff08;Server&#xff09;与客户端&#xff08;Client&#xff09;的关系。 蓝牙配置文件&#xff08;B…

4-1指令系统-指令格式

文章目录一.指令的基本格式1.结构2.长度3.根据操作数地址码数目分类&#xff08;1&#xff09;零地址指令&#xff08;2&#xff09;一地址指令&#xff08;3&#xff09;二地址指令&#xff08;4&#xff09;三地址指令&#xff08;5&#xff09;四地址指令二.扩展操作码指令格…

Maven学习(二):Maven基础概念

Maven基础概念一、仓库二、坐标三、全局setting与用户setting区别一、仓库 仓库&#xff1a;用于存储资源&#xff0c;包含各种jar包&#xff1b;仓库分类&#xff1a; 本地仓库&#xff1a;自己电脑上的存储仓库&#xff0c;连接远程仓库获取资源&#xff1b;远程仓库&#x…

信息论复习—离散信道及其容量

目录 信道的简介&#xff1a; 信道的分类&#xff1a; 离散无记忆信道&#xff08;DMC&#xff09;模型&#xff1a; 转移概率&#xff1a; 离散无记忆信道的转移矩阵 输出仅与当前的输入有关&#xff1a; 后验概率&#xff1a; 离散无记忆信道的后验概率矩阵 &#xf…

spring-boot-starter-jdbc和mysql-connector-j依赖爆红的解决办法

spring-boot-starter-jdbc和mysql-connector-j依赖爆红的解决办法 目录spring-boot-starter-jdbc和mysql-connector-j依赖爆红的解决办法出现问题之前出现的问题&#xff1a;解决办法&#xff1a;方案一&#xff1a;第一种是继承 spring-boot-starter-parent 然后 依赖覆盖方案…

怎么用Python测网速?

“speedtest-cli” 是一个 Python 的第三方库&#xff0c;它可以用来在命令行中测试网络速度。它使用了 Speedtest.net 的服务器来进行测速&#xff0c;并可以提供下载和上传速度、延迟、丢包率等信息。使用这个库可以很方便地在终端中测试网络速度&#xff0c;而无需在浏览器中…

轻量级代码生成器加测试数据生成器

轻量级代码生成器加测试数据生成器介绍代码生成常用注解基本使用全局控制属性模板文件相关属性模板文件配置模拟数据生成自定义词库索引注意事项从已经存在的表完成映射,生成模板代码使用步骤Gitee项目链接 介绍 本项目是一个轻量级代码生成器,并提供多种方式来完成模拟数据的…

力扣(LeetCode)2299. 强密码检验器 II(C++/Python3)

题目描述 模拟 仅当密码包含强密码的所有特性&#xff0c;它是一个 强 密码。提示我们&#xff0c;遍历密码&#xff0c;维护 444 个标志&#xff0c;标志记录特性。遍历结束&#xff0c;根据标志判断特性。 class Solution { public:bool strongPasswordCheckerII(string pa…

MySQL建立数据库时字符集和排序规则的选择

文章目录前言一、字符集&#xff1f;二、Mysql中的字符集1.Unicode与UTF8、UTF8MB4、UTF16、UTF32关系2.Mysql新建数据库时选择哪种字符集呢&#xff1f;三、Mysql排序规则四、Mysql查询字符集和排序规则常用的命令前言 在MySQL中&#xff0c;字符集和排序规则是区分开来的&am…

【ArcGIS 小贴士】Pro VS ArcMap及软件获取

有朋友问我&#xff0c;ArcGIS Pro是不是比ArcMap好用。 我觉得用Pro的感觉&#xff0c;用Pro的感觉比ArcMap Ribbon界面 Pro采用的是Ribbon用户界面&#xff0c;与现在的微软的Office软件相似&#xff0c;功能的组织更加清晰。10.x版本的ArcGIS则是传统的工具条界面 有些朋友…

day42|● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

1049. 最后一块石头的重量 II 1.代码 class Solution { public:int lastStoneWeightII(vector<int>& stones) {int sum 0;for(int i: stones) {sum i;}int t sum;sum sum /2;vector<int>f(sum 1);for (int i 0; i < stones.size(); i) {for (int j …

【Pytorch基础(2)】张量的索引,切片与维度变换

一、张量的维度索引 张量的索引是从第零维度开始的。让我们来创建一个四维的张量做举例说明&#xff1a;torch.Tensor(2,3,64,64) 此时&#xff0c;这个张量可以表示两张边长为64的正方形彩色图像&#xff0c;具体来说&#xff0c;张量的第零维表示图像的数量&#xff1b;第一…

Apollo星火计划学习笔记——Control 专项讲解(LQR)

文章目录1. 算法相关基础1.1 一阶倒立摆1.2 二自由度车辆横向跟踪偏差模型1.3 车辆横向跟踪偏差模型1.4 车辆横向跟踪偏差倒车模型1.5 轮胎侧偏角与侧偏刚度1.6 LQR 线性二次型问题:2. LQR代码解析2.1 WriteHeaders&#xff08;调试过程中的状态量&#xff09;2.2 LatControlle…

Android APK 瘦身

Android APK 瘦身的几个方法将项目中的图片由png、jpg转为webp格式。如下操作&#xff1a;1.1选中图片或者含有图片的文件夹 右键选择Convert toWebP..1.2根据自身情况选择有损压缩还是无损压缩备注&#xff1a;官网连接&#xff1a;https://developer.android.google.cn/studi…

leetcode-每日一题-强密码检验器II(简单,数学逻辑)

如果一个密码满足以下所有条件&#xff0c;我们称它是一个 强 密码&#xff1a;它有至少 8 个字符。至少包含 一个小写英文 字母。至少包含 一个大写英文 字母。至少包含 一个数字 。至少包含 一个特殊字符 。特殊字符为&#xff1a;"!#$%^&*()-" 中的一个。它 不…

Golang 从菜鸟到大咖的必经之路_GO 语言的转义字符、注释、规范和代码风格要求

目录 一、GO 语言转义字符 A.Golang 常用的转义字符&#xff08;escape char&#xff09;: B.课程练习 二、Go 语言注释&#xff1a; A.注释&#xff08;Comment&#xff09;: B.Go 语言中的注释类型&#xff1a; C.注释不会被编译 D.shifttab 三、规范的代码风格要求…

聚焦儿童羽绒服产业,看用友YonSuite打造领先实践的数智创新小灯塔

有一种冷“是妈妈觉得你冷”。每每想起小时候&#xff0c;为了应对寒冷的冬季&#xff0c;都会“全副武装”&#xff0c;裹得厚厚的&#xff0c;里三层外三层。 放到如今&#xff0c;有了羽绒服的萌娃们&#xff0c;已不再像我们当年一样穿得厚厚的了。现在的年轻爸妈喜欢装扮…

Udev 为设备节点起别名

查看设备信息&#xff1a; 操作udev&#xff0c;可以使用udevadm命令&#xff0c;如果我们要查看/dev/sda 设备节点信息&#xff0c;我们可以使用下面命令&#xff1a; 命令&#xff1a;udevadm info -a --namesda rootubuntu:/sys/kernel/debug/usb# udevadm info -a --nam…

【C语言】文件操作(1)

文件操作一、关于文件的基础知识1.为什么要学习文件2.什么是文件3.文本文件与二进制文件二、文件的打开和关闭1. 文件指针2.文件的打开和关闭3.文件结尾三、文件的顺序读写1.fputc与fgetc2.fputs与fgets3.fprintf与fscanf4.fwrite与fread5.三个标准流一、关于文件的基础知识 1…