组件间通信方式

2023-11-04

方式一:props

适用于:父子组件间通信

1、父给子

父组件给子组件传递数据(非函数):本质其实是父组件----->子组件传递数据

//父组件App.vue
<template>
	<div>
		<Student name="李四" sex="女" :age="18"/>
	</div>
</template>
<script>
	import Student from './components/Student'
	export default {
		components:{Student}
	}
</script>
//子组件
<template>
	<div>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<h2>学生年龄:{{myAge+1}}</h2>
		<button @click="updateAge">尝试修改收到的年龄</button>
	</div>
</template>
<script>
	export default {
		data() {
			return {
				myAge:this.age
			}
		},
		methods: {
			updateAge(){
				this.myAge++
			}
		},
		//props的三种接收方式
		//1、简单声明接收
		// props:['name','age','sex'] 

		//2、接收的同时对数据进行类型限制
		/* props:{
			name:String,
			age:Number,
			sex:String
		} */

		//3、接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
		props:{
			name:{
				type:String, //name的类型是字符串
				required:true, //name是必要的
			},
			age:{
				type:Number,
				default:99 //默认值
			},
			sex:{
				type:String,
				required:true
			}
		}
	}

2、子给父

父组件给子组件传递数据(函数类型):本质其实是子组件----->父组件传递数据
通过父组件给子组件传递函数类型的props实现:子给父传递数据

//父组件APP.vue中
<template>
	//1、父给子传递一个函数
	<School :getSchoolName="getSchoolName"/>
</template>
<script>
export default {
	components:{School},
	data() {
			return {
				schoolName:''
			}
		},
	methods:{
		//2、声明这个函数
		getSchoolName(name){
				console.log('App收到了学校名:',name)
				this.schoolName = name
			},
	}
}
</script>
//子组件School.vue中
<template>
	//4、写点击事件
	<button @click="sendSchoolName">把学校名给App</button>	
</template>
<script>
.......
export default {
	//3、子组件声明接收函数
	props:['getSchoolName'],
	data(){
		return {
			name:'xxxxxx'
		}
	},	
	methods: {
			//5、写点击事件的函数
			sendSchoolName(){
				//6、调用接收到的函数,传参数
				this.getSchoolName(this.name)
			}
		},
}
</script>

方式二、组件自定义事件

适用于:子给父传递数据。通过父组件给子组件绑定一个自定义事件

1、子给父

写法1($emit)

在谁身上绑定的自定义事件就去谁身上触发(或解绑),下面代码中给子组件Student身上绑定(用@/v-on)了自定义事件demo,应该去Student身上触发(用$emit)

//父组件App.vue
<template>
	//1、通过父组件给子组件绑定一个自定义事件demo实现:子给父传递数据(使用@或v-on)。这个事件demo对应一个回调函数getStudentName
	<Student @demo="getStudentName" />
</template>
<script>
.........
	export default {
		components:{Student},
		data() {
			return {
				studentName:''
			}
		},
		methods: {
			//2、声明回到调函数  当子组件用$emit触发这个自定义事件demo后会执行事件对应的回调函数,这个回调函数能接收到触发自定义事件的组件(即本例的子组件)传过来的参数
			getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			},
</script>
//子组件
<template>
	<div class="student">
		//3、给点击事件绑定回调函数
		<button @click="sendStudentlName">把学生名给App</button>
		<button @click="unbind">解绑demo事件</button>
		<button @click="death">销毁当前Student组件的实例(vc)</button>
	</div>
	<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
			}
		},
		methods: {
			//4、写触发点击事件后调用的回调函数
			sendStudentlName(){
				//5、用$emit方法触发Student组件实例身上的demo事件,同时把子组件的数据传给了父组件
				this.$emit('demo',this.name,666,888,900)
			},
			unbind(){
				this.$off('demo') //解绑一个自定义事件
				// this.$off(['demo','demo1']) //解绑多个自定义事件
				// this.$off() //解绑所有的自定义事件
			},
	</script>
</template>

写法2($on)

与写法1不同的是,用ref代替了v-on/@,同时增添了一个监听($on)的步骤

//父组件App.vue
<template>
	//1、通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(使用@或v-on)
	<Student ref="student"/>
</template>
<script>
.........
	export default {
		components:{Student},
		data() {
			return {
				studentName:''
			}
		},
		methods: {
			//3、声明demo事件对应的回调函数
			getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			},
		mounted() {
			//2、
			//this.$refs.student:拿到了组件的实例对象Student。然后用$on方法监听demo自定义事件,如果demo事件被触发,则调用demo事件对应的回调函数,同时这个回调能收到传过来的参数
			this.$refs.student.$on('demo',this.getStudentName) 
			//绑定自定义事件(一次性)
			// this.$refs.student.$once('atguigu',this.getStudentName) 
		},
	}
</script>
//子组件与写法1中的相同

方式三、全局事件总线$bus

适用于:任意组件间通信(子给父、父给子、兄弟给兄弟)

任意组件间

用兄弟组件间通信来举例

//main.js
.............
new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus = this //1、安装全局事件总线。让所有组件都能用$bus
	},
})

student组件给school组件传数据
school组件作为想要接收数据的一方,需要先在全局事件总线上绑定自定义事件,由于在自己组件内给$bus绑定的事件,该事件对应的回调函数自然就留在了自己组件内。

//school组件
<template>
	......
</template>
<script>
export default {
  name: "School",
  mounted() {
    // console.log('School',this)
    // 在这个组件内给全局事件总线$bus绑定了自定义事件hello,
    // 但是这个自定义事件对应的回调是留在了这个组件内
    // 如果别的组件触发$bus身上的自定义事件hello,该事件对应的回调就会执行
    // 该回调在那个组件内,那个组件就能收到触发事件的组件传过来的数据
    //2、
    this.$bus.$on("hello", (data) => {
    	//6、执行自定义事件对应的回调,同时能接收到数据
      console.log("我是School组件,收到了数据", data);
    });
  },
  beforeDestroy() {
  	//解绑自定义事件
    this.$bus.$off("hello");
  },
};
</script>

如果student组件想给school组件传递数据,就可以触发school组件在$bus身上绑定的自定义事件,同时传递数据。由于自定义事件被触发,对应的回调函数(留在school组件内)也会执行,该回调函数能接收到传递过来的数据

//student组件
<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		//3、绑定点击事件
		<button @click="sendStudentName">把学生名给School组件</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
		methods: {
		   //4、声明点击事件对应的回调
			sendStudentName(){
				//5、该回调触发自定义事件,同时传递数据
				this.$bus.$emit('hello',this.name)
			}
		},
	}
</script>

方式四、消息订阅与发布pubsub.js

适用于:任意组件间通信(react中用的多,vue中用的少)

任意组件间

用兄弟组件间通信来举例
student组件给school组件传数据

//安装库
npm i pubsub-js

school组件拿到student组件的数据,即school组件是作为订阅消息的一方。

//school组件
<template>
	..............
</template>
<script>
	//引入库
	import pubsub from 'pubsub-js'
	export default {
		name:'School',
		mounted() {
			//订阅消息hello,如果发布了消息hello,就执行该消息对应的回调函数,同时拿到传递的数据。msgName是消息名,data才是传递的数据。
			//每次订阅都是不同的id
			this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
				console.log(this)
				// console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
			})
		},
		beforeDestroy() {
			pubsub.unsubscribe(this.pubId)
		},
	}
</script>

而student组件是发布消息的一方

//student组件
<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		//点击事件
		<button @click="sendStudentName">把学生名给School组件</button>
	</div>
</template>
<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
		methods: {
			//点击事件对应的回调函数
			sendStudentName(){
				//执行该回调函数,则发布消息hello,同时传递数据
				pubsub.publish('hello',666)
			}
		},
	}
</script>

方式五、Vuex

适用于:任意组件间通信

方式六、插槽

适用于:父子组件通信(一般结构)

默认插槽

具名插槽

作用域插槽

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

组件间通信方式 的相关文章

随机推荐

  • 网络安全之信息收集

    第一部分 被动信息收集 如果你对网络安全入门感兴趣 那么你需要的话可以点击这里 网络安全重磅福利 入门 进阶全套282G学习资源包免费分享 1 简介 在信息收集这块区域 我将其分为两部分 第一部分即被动信息收集 第二部分即主动信息收集 对于
  • zerotier源码编译注意事项

    1 事先安装好rust 后续编译中会用到cargo 2 切换镜像源后在make Rust使用国内Crates 源 rustup源 字节跳动新的 Rust 镜像源以及安装rust rust 国内源 西京刀客的博客 CSDN博客 3 如果是比较
  • 2022杭电多校(十)

    2022杭电多校 十 文章目录 2022杭电多校 十 一 比赛小结 二 题目分析及解法 基础题 1001 Winner Prediction 1003 Wavy Tree 1004 Average Replacement 1007 Even
  • idea设置包分成显示

    分层显示之前 分层设置 取消分层显示后
  • 各种系统架构图与详细说明

    原文 各种系统架构图与详细说明 共享平台逻辑架构设计 如上图所示为本次共享资源平台逻辑架构图 上图整体展现说明包括以下几个方面 1 应用系统建设 本次项目的一项重点就是实现原有应用系统的全面升级以及新的应用系统的开发 从而建立行业的全面的应
  • 两个栈实现一个队列的功能

    1 栈 是限制的线性表插入删除必须在同一端完成 栈的特点 先进后出 入栈将数据沉入栈底 最上面的一个数据是栈顶 获取栈顶元素Top 之后要进行Pop 删除栈顶 才可以取到第二个数据 2 队列 也是对线性表的一种限定 规定插入删除数据必须在异
  • R手册(Syntax)--magrittr

    magrittr pipe lhs gt rhs forward pipe lhs为rhs第一个参数时 x gt f y 等价于 f x y lhs在任意位置时 用点 代替 z gt f x y arg 等价于 f x y arg z rh
  • codeforces 851 #432 div2 C Five Dimensional Points

    Problem codeforces com contest 851 problem C Preference Codeforces Round 432 editorial Codeforces Round 432 Div 2 C Five
  • 华为OD机试 - 单词接龙(JS)

    题目描述 单词接龙的规则是 可用于接龙的单词首字母必须要前一个单词的尾字母相同 当存在多个首字母相同的单词时 取长度最长的单词 如果长度也相等 则取字典序最小的单词 已经参与接龙的单词不能重复使用 现给定一组全部由小写字母组成单词数组 并指
  • 6.5 Java, JDBC, and MySQL Types

    MySQL Connector J 在处理 MySQL 数据类型和 Java 数据类型之间的转换方面非常灵活 通常 任何 MySQL 数据类型都可以转换为 java lang String 任何数字类型都可以转换为任何 Java 数字类型
  • VTK编译笔记

    VTK 是一个用于计算机图形学 可视化和图像处理的开源 面对对象软件系统 准备工具 编译 VTK 需要以下工具 括号内是本例中使用的版本 VTK 源码包 https vtk org download 本例下载的是 VTK 9 2 0 rc1
  • 【工具】推荐一个开源小巧的pdf分析工具

    如何定位pdf的坐标 这是最近我遇到的问题 因为我需要把几个字类似水印通过java写到pdf上 搜了几个都说要用AcrobatCD软件 这个软件也下了但是发现并没有网格坐标的功能 不知道是不是要收费 还有就是gimp软件好像也能看pdf坐标
  • vue 发送ajax请求

    一 简介 1 vue本身不支持发送AJAX请求 需要使用vue resource vue1 0版本 axios vue2 0版本 等插件实现 2 axios是一个基于Promise的HTTP请求客户端 用来发送请求 也是vue2 0官方推荐
  • Functional Programming in Java venkat(15) Being Lazy part2

    Functional Programming in Java venkat 15 Being Lazy part2 这里是记录学习这本书 Functional Programming in Java Harnessing the Power
  • 双向可控硅

    转载于 http www baiheee com Documents 100830 100830085212 htm 双向可控硅是在单向可控硅的基础上发展起来的 顾名思义 它是 种具有双向导电特从外形上看双向可控硅和单向可控硅很相似 同样有
  • Qt绘制指针时钟

    Qt绘制指针时钟 什么是Qt Qt是一款跨平台的C 应用程序开发框架 它提供了一套完整的工具和库 可以帮助开发者快速构建高质量的应用程序 Qt支持多种操作系统和开发语言 包括Windows Linux macOS Android iOS等
  • spring boot学习(转)

    玩转Spring Boot 前言 首先在这里对Spring Boot做个简单的介绍 对Spring Boot也关注了挺久了 Spring Boot是由Pivotal团队提供的全新框架 Pivotal团队在2014年4月份发布第一个GA版本
  • SpringBoot学习笔记

    微服务阶段 JavaSE 面向对象 MySql JDBC 持久化存储 html css JavaScript Jquery 框架 视图 框架 JavaWeb 开始独立开发MVC三层架构的网站 原始 SSM 框架 简化了我们的开发流程 配置也
  • Lady General Hua Mu-lan花木兰剧本

    Lady General Hua Mu lan花木兰剧本 Gary专业版 Scene 0 Narrator N Oh come here little girl tell me do you want to become a woman a
  • 组件间通信方式

    方式一 props 适用于 父子组件间通信 1 父给子 父组件给子组件传递数据 非函数 本质其实是父组件 gt 子组件传递数据 父组件App vue