Vue组件通信方式
父组件向子组件传递数据
props 方法
理解
父传子,使用props方法理解为vx转账300块模式,父组件中使用的子组件标签中发起转账,子组件需要在配置中使用props进行确认收款。
具体过程
核心代码展示
// 这里是父组件 father.vue
<template>
<div>
<Son :money="100">
</div>
</template>
// 这里是子组件 son.vue
<template>
<div>
<h1>收款金额:{{myMoney}}</h1>
</div>
</template>
<script>
export default{
data(){
return {
myMoney:this.money
}
},
props:['money']
/* 完整
props:{
money:{
type:Number,
required:true,
default:0
}
}
*/
}
</script>
注意事项
props是只读,子组件不能直接对接收过来的数据直接修改,会报错!!
所以得向上面例子一样,最好在子组件中data中,声明一个新的变量去存,然后在应用中使用新变量,这样在子组件中改新变量就不会报错了
一个小细节,props接收过来的变量数据优先级高于该组件中data声明的,不然data里面写的myMoney=this.money 中的money不先出现在vueComponents上,上哪里去找money赋给myMoney
子组件向父组件传递数据
props方法
理解
回顾一下父传子的props,父组件中的数据通过在子组件中props接收就能用;
在子传父的props中,需要在父中先定义一个methods方法,然后在子组件标签上动态绑定上;然后在子组件中props接收这个方法,在子组件中发送的事件里面去调用这个接收到的方法
具体过程
// 这是父组件,father.vue
<template>
<div>
<Son :getMes="getMes">
</div>
</template>
<script>
export default{
methods:{
getMes(mes){
console.log('father接受到了消息', mes)
}
}
}
</script>
// 这里是子组件 son.vue
<template>
<div>
<button @click="sendMes">一键发送</button>
</div>
</template>
<script>
export default{
data(){
return {
mes:'hahaha'
}
},
props:['getMes'],
methods:{
sendMes: {
this.getMes(mes)
}
}
}
</script>
$emit自定义事件
理解
在父组件中,通过给子组件标签中添加一个自定义事件,在子组件中触发这个自定义事件,通过父中提前写好的methods中的回调函数,实现子传父。
具体过程
// 这是父组件,father.vue
<template>
<div>
<Son v-on:defOwn="getMes"> // 写@替代v-on当然可以
<h1>接受到来自子组件的信息:{{fromSonMes}}</h1>
</div>
</template>
<script>
.....//省略引入等代码
export default{
....// 省略其他配置
data(){
return {
fromSonMes:''
}
}
methods:{
getMes(mes){
console.log('father接受到了消息', mes)
this.fromSonMes = mes
}
/*
ps:如果传多项数据,接受直接用对象,用数组接
getMes(mes,...params){
console.log('father接受到了消息', mes,params)
}
*/
}
}
</script>
// 这里是子组件 son.vue
<template>
<div>
<button @click="sendMes">一键发送</button>
</div>
</template>
<script>
export default{
data(){
return {
mes:'hahaha'
}
},
methods:{
sendMes: {
this.$emit('defOwn',this.mes)
}
}
}
</script>
当然还有第二种写法,不适用v-on去绑定,用ref,子组件写法相同,父组件需要改
// 这是父组件,father.vue
<template>
<div>
<Son ref="son"> // 写@替代v-on当然可以
</div>
</template>
<script>
.....//省略引入等代码
export default{
....// 省略其他配置
methods:{
getMes(mes){
console.log('father接受到了消息', mes)
}
},
mounted(){
this.$refs.son.$on('defOwn',this.mes)
// 注意!!!
/* methods中不写getMes(),把它换到mounted中
this.$refs.son.$on('defOwn',function(mes){
console.log(this)
})
//这个this指向son实例对象,
因为调用动作触发的是son组件,function自然指向调用者。
解决方案可以写箭头函数
*/
}
}
</script>
兄弟组件通信
$bus(全局事件总线)
理解
通俗说就是整一个所有组件(不管嵌套在任何地方)都能看见的bus上,每个组件都能从坐这个车拿到想要的地方。
深度理解:Vue有一个重要的内置关系就是
- VueComponent.prototype.__ proto __ === Vue.prototype
这两个相等代表着组件实例对象可以访问到最初的Vue原型上的方法
tips
使用vue-cli创建一个项目,vue的内置属性prototype指向我们main.js中new出来的Vue实例对象(vm),vm.__proto__又指向了Vue的原型对象;前置知识点:Vue.prototype指向的就是Vue的原型对象;
不理解画图,画出来vue , vue实例对象(vm) ,vue的原型对象。三者之间形成三角杀,所以,组件实例对象可以访问到最初的Vue原型上的方法
具体过程
// 这里是main.js 文件
... // 省略前面引入
new Vue({
el:'app',
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus = this // 安装全局事件总线
}
})
下面我们距离bro组件接收,sis组件发送
// bro文件,接收方
<script>
export default{
mounted(){
this.$bus.$on('hello',(data)=>{
console.log('我是bro收到数据',data)
})
}
}
</script>
// sis文件,发送方
<template>
<div>
<button @click="sendMes">点击发送信息</button>
</div>
</template>
<script>
export default{
data(){
return{
data:'你好'
}
}
methods:{
sendMes(){
this.$bus.$emit('hello',this.data)
}
}
}
</script>