vue学习之父组件与子组件之间以及兄弟组件之间的通信

vue最大的优点是好维护,复用率高。其中最主要的原因就是一个页面是有很多个子组件拼接起来的,座椅哪个模块需要优化改变,只需要去修改对应的组件即可。所以,各个组件之间肯定是需要相互联系,相互通信的。现在,我们来看下父子组件之间如何相互通信。

1:父组件向子组件输送数据,主要通过props属性。props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义校验和设置默认值


这是父组件,其中message是父组件想要传递给子组件的值。



这是子组件,其中,子组件想要接收到父组件传过来的值,主要就是通过props参数,该参数里主要说明想要接收哪个父组件传过来的值。

除此以外,还可以通过v-bind动态绑定想要传递给子组件的值
<template>
  <div class="parent">
    <span>我是父组件</span>
    <child v-on:childToParentMsg="showChildToParentMsg" v-bind:parentToChild="parentMsg"></child>
  </div>
</template>
<script>
  import child from '../components/child'
  export default{
      name:"parent",
    data(){
      return {
      	parentMsg:'我是父组件传递给子组件的数据'
      }
    },
    methods: {
      showChildToParentMsg:function(data){
        alert("父组件接收子组件的信息:"+data)
      }
    },
    components: {child}
  }
</script>

其中,通过v-bind指令绑定想要传递给子组件的变量信息,不要忘了在父组件中的data对象中注册该变量。

<template>
  <div class="child">
    <span>我是子组件</span>
    <button v-on:click="childToParent">点我向父组件传值</button>
    <div id="">
    	这是子组件接收的父组件传过来的的数据:
    	<div style="color: red;">{{parentToChild}}</div>
    </div>
  </div>
</template>
<script>
  export default{
    name: 'child',
    data(){
      return {}
    },
    methods: {
      childToParent(){
        this.$emit("childToParentMsg", "我是子组件向父组件传的值");
      }
    },
    props:["parentToChild"]
  }
</script>

这里接收父组件的传值跟第一种是一样的,在props属性中指定要接收的变量名称,然后绑定到视图中。

这里说一下,props可以是一个数组,也可以是一个对象。props除了指定接收的变量意外,还可以给接受的变量做一些规定。比如接收数据的类型,是否必需,或者通过定义validator函数来自定义业务逻辑。

比如

props:{
  message:{
  type:String,
  required:true
  },
  age:{
  type:Number,
  default:18,
  validator:function(value){
  return value>=0
  }

  }

这里制定接收的meaasge变量是字符串类型,而且是必需的

age是number类型,而且如果没有age没有给指定值的话默认就是18,并且规定传值的话值必需大于0

props是单向数据流,也就是说父组件传递给子组件的数据,当父组件中该数据改变时,子组件会随之改变,但是,如果子组件不能直接修改改数据。如果子组件想要修改该数据的话,可以将该数据赋值给自己的一个变量。然后通过修改该变量来修改接收到的数据。但是父组件中该变量不会随之改变。

那么问题来了,怎么能修改子组件中接收得来自父组件的变量,并且让父组件也随之改变呢。

有一个比较简单的方法,就是利用对象的特征,把父组件想要传递给子组件的变量封装在对象中传递,这样在子组件中修改属性的时候,由于指向的是同一个地址,那父组件肯定也会随之改变。



2:子组件向父组件传输数据,主要是通过$emit自定义方法,将数据传递到父页面,父组件通过v-on来监听子组件通过$emit自定义的方法,这里子组件通过点击执行childParent方法,在该方法里,使用$emit自定义变量childToParentMsg,就像键值对一样,将要传递给子组件的值通过该变量传递。

<template>
  <div class="child">
    <span>我是子组件</span>
    <button v-on:click="childToParent">点我向父组件传值</button>
    <div id="">
    	这是子组件接收的父组件传过来的的数据:
    	<div style="color: red;">{{parentToChild}}</div>
    </div>
  </div>
</template>
<script>
  export default{
    name: 'child',
    data(){
      return {}
    },
    methods: {
      childToParent(){
        this.$emit("childToParentMsg", "我是子组件向父组件传的值");
      }
    },
    props:["parentToChild"]
  }
</script>

父组件主要是通过v-on指令监听子组件通过$emit自定义的变量名称,并且自定义方法,在该方法中传入参数,则改参数即代表子组件传递来的数据。

<template>
  <div class="parent">
    <span>我是父组件</span>
    <child v-on:childToParentMsg="showChildToParentMsg" v-bind:parentToChild="parentMsg"></child>
  </div>
</template>
<script>
  import child from '../components/child'
  export default{
      name:"parent",
    data(){
      return {
      	parentMsg:'我是父组件传递给子组件的数据'
      }
    },
    methods: {
      showChildToParentMsg:function(data){
        alert("父组件接收子组件的信息:"+data)
      }
    },
    components: {child}
  }
</script>

好了,现在看下效果图


$emit()第一个参数是提交的事件,后面的参数是要提交的数据,数据可以不止一个,也可以是对象

比如: this.$emit('childToParentMsg',this.childInfor,this.type)

也就是说除了第一个提交的事件意外,后面的参数可以有很多个。当然,父组件监听接收子组件传递的信息的函数中也应该对应有相同的参数个数。

3:两个组件之间除了可能成为父子组件,还可能成为兄弟组件,那么兄弟组件之间该如何通信呢

兄弟元素之间的通信的关键点呢是创建一个空的vue实例作为中转站

在模块化开发过程中我们首先新建一个新的js文件,在该文件中创建一个空的vue实例,我们这里新建的是bus.js

import Vue from 'vue';
export default new Vue();

为了清晰地看出效果,我这里创建了三个组件,分别是parent.vue,child.vue,twochild.vue,parent.vue是父组件,剩下的两个是子组件,这里主要就是展示剩下的两个兄弟组件之间如何进行通信

<template>
	<div>
		<child></child>
		<childs></childs>
	</div>
</template>
<script>
import child from '../components/child'//引入第一个子组件
import childs from '../components/twochild'//引入第二个子组件
export default {
  data(){
  	return{
  	}
  },
  components:{child,childs}
}
</script>

下面主要是child.vue向twochild组件发送数据

下面是child.vue的内容

<template>
	<div>
		<button @click="send">点击我向兄弟组件发送数据</button>//点击执行send事件
	</div>
</template>
<script>
import Bus from '../bus.js'//这里是引入bus.js,作为中转站
export default {
  data(){
  	return{
  		'infor':'我是发送给兄弟元素的数据'
  	}
  },
 methods:{
	send:function(){
		Bus.$emit('dataChild',this.infor)//主要利用$emit提交dataChild事件,把想要发送的infor发送出去
	}
 }
}
</script>

这里说下关键点

1:引入中转站,也就是bus.js

2:通过$emit来触发事件,发送数据

下面看下twochild.vue

<template>
	<div>
		从兄弟元素接收数据主要是通过中转站:{{name}}
	</div>
</template>
<script>
import Bus from '../bus.js'
export default {
  data(){
  	return{
  		name:''
  	}
  },
 created(){
 	var that=this;
 	Bus.$on('dataChild',infor=>{
 		that.name=infor
 	})
 }
}
</script>

这里的要点就是

1:也是首先引入中转站bus.js

2:通过$on来监听$emit提交触发的事件,在回调函数中接收数据。

看下结果

点击按钮,发送数据,结果如下


好了,可以清楚的看不到twochild.vue拿到了child发送的数据

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值