Vue组件间通信

props

用于父组件给子组件传值

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

props接收时有三种形式:

  1. 默认接收:prop:['name']
  2. 限制类型接收:props:{name:String}
  3. 限制类型、必要性、指定默认值:
props:{
	name:{
		type:String,
		required:true,
		default:'zhangsan'
	}
}

父组件在子组件身上传递数据:

<template>
	<div>
		<Student name="zhangsan" sex="男" :age="18"/>
	</div>
</template>

<script>
	import Student from './components/Student'
	export default {
		name:'App',
		components:{Student}
	}
</script>

子组件通过props属性接收父组件传递的数据:

<template>
	<div>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<h2>学生年龄:{{age}}</h2>
	</div>
</template>

<script>
	export default {
		name:'Student',
		props:{
			name:{
				type:String, //name的类型是字符串
				required:true, //name是必要的
			},
			age:{
				type:Number,
				default:18 //默认值
			},
			sex:{
				type:String,
				required:true
			}
		}
	}
</script>

注意:data中的数据是可读可写的;props中的属性只是可读的,无法重新赋值,重新赋值会报错(也就是说,子组件不要直接去修改父组件中的数据)。

自定义事件

用于子组件给父组件传递数据

子组件中触发自定义事件(触发emit事件)

比如在子组件中有一个点击事件:点击事件中的方法中this.$emit(‘自定义事件名称’,传递的参数)

<template>
	<div class="student">
		<h2>姓名:{{name}}</h2>
		<h2>性别:{{sex}}</h2>
		<h2>年龄:{{age}}</h2>
		<button @click="sendStudentlName">把姓名传递给App</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
				age:18
			}
		},
		methods: {
			sendStudentlName(){
				//触发Student组件实例身上的transmit事件
				this.$emit('transmit',this.name,666,888,900)
			},
		},
	}
</script>

<style>
</style>

父组件定义自定义事件并接收数据

在父组件中的子标签上写自定义事件及方法@自定义事件名称=“方法名称”

<template>
	<div class="app">
		<h1>学生姓名是:{{studentName}}</h1>
		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(使用@或v-on使用ref) -->
		<Student ref="student" @click.native="show"/>
	</div>
</template>

<script>
	import Student from './components/Student'

	export default {
		name:'App',
		components:{Student},
		data() {
			return {
				studentName:''
			}
		},
		methods: {
			getStudentName(name){
				this.studentName = name
			},
			show(){
				alert('tt')
			}
		},
		mounted() {
			this.$refs.student.$on('transmit',this.getStudentName) //绑定自定义事件
		},
	}
</script>

<style>
</style>

全局事件总线

一种适用于任意组件间的通信方式
安装全局事件总线:

在入口文件main.js中在使用beforecreate实例初始化之后安装

import Vue from 'vue'
import App from './App.vue'

new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线
	},
})

$bus就是当前应用的vm实例

使用事件总线:

传递数据:this.$bus.$emit('***',data)

接收数据:this.$bus.$on('***',this.方法名)/this.$bus.$on('***',回调函数)
(回调函数写成箭头函数形式)

最后最好在beforeDestroy钩子中使用$off对当前组件所使用到的事件进行解绑

<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<button @click="sendStudentName">把学生名传递给School组件</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
		methods: {
			sendStudentName(){
				this.$bus.$emit('hello',this.name)
			}
		},
	}
</script>

<style>

</style>

<template>
	<div class="school">
		<h2>姓名:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>
	export default {
		name:'School',
		data() {
			return {
				name:'李四',
				address:'北京',
			}
		},
		mounted() {
			this.$bus.$on('hello',(data)=>{
				console.log(data)
			})
		},
		beforeDestroy() {
			this.$bus.$off('hello')
		},
	}
</script>

<style>

</style>

$on:绑定事件;$emit:触发事件;$off:解绑事件

消息订阅与发布

通过pubsub.js插件,可用于任意组件间通信
1.安装插件:npm i pubsub-js
2.引入:import pubsub from 'pubsub-js'
3.数据发送:pubsub.publish('xxx',数据)
4.数据接收:pubsub.subscribe('xxx',data)

数据发送:

<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(){
				pubsub.publish('hello',this.name)
			}
		},
	}
</script>

<style>

</style>

数据接收:

<template>
	<div class="school">
		<h2>姓名:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'School',
		data() {
			return {
				name:'李四',
				address:'北京',
			}
		},
		mounted() {
			this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
				console.log(data)
			})
		},
		beforeDestroy() {
			pubsub.unsubscribe(this.pubId)
		},
	}
</script>

<style>

</style>

最后也最好在beforeDestroy钩子中使用 PubSub.unsubscribe(pid)取消订阅

Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex组件间通信

插槽

slot插槽

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值