Vue组件之间的通讯方式

目录

  • Vue组件之间的通讯方式
    • 1. 父子通讯
      • 1.1 属性传递
      • 1.2 方法传递
      • 1.3 $parent获取方法和属性
    • 2. 子父通讯
      • 2.1 属性传递
      • 2.2 通过`$refs`主动获取子组件方法和属性
      • 2.3 通过`$children`主动获取子组件方法和属性
    • 3. 兄弟通讯
      • 3.1 通过共同的父亲进行传递信息
      • 3.2 通过event bus通讯
      • 3.3 通过PubSub通讯
      • 3.4 通过Vuex通讯

Vue组件之间的通讯方式

github源码地址:详情点击

前提

  • 这里我们使用了vue/cli4使用默认配置常见的项目,详情 点击
  • 创建好项目之后我们需要这样做
    1. components的文件夹下新建名为Parent.vueChildOne分别充当父组件和子组件。
    2. 然后在App.vueParent.vue中映射成组件标签

基本结构如下
Parent.vue

<template>
    <div>
    	<h1>Parenth1>
        <child-one>child-one>
    div>
template>

<script>
import ChildOne from '@/components/ChildOne'
export default {
    data () {
        return {
            
        }
    },
    components:{
        ChildOne
    }
}
script>

ChildOne.vue

<template>
    <div>
        <h1>ChildOneh1>
    div>
template>

<script>
export default {
};
script>

1. 父子通讯

1.1 属性传递

通过组件标签传递属性进行通讯

  • 我们在在文件中添加相应的代码

Parent.vue

  • template
    <div>
        <h1>Parenth1>
        <child-one :msgToChild="msg">child-one>
    div>
  • script
    data () {
        return {
            msg:'i am you father'
        }
    },

ChildOne.vue

  • template
    <div>
        <h1>ChildOneh1>
        <div>接收到父亲传来的消息:{{msgToChild}}div>
    div>
  • script
export default {
    props:['msgToChild']
};
  • 当我们启动项目打开浏览器的时候,就会看到界面
    Vue组件之间的通讯方式_第1张图片
  • 这就是说明我们父组件向子组件传递消息成功

1.2 方法传递

通过组件标签进行方法的传递,子组件$emit触发方法

父组件Parent.vue

  • template
  
  <child-one :msgToChild="msg" @methodToChild="showMsg">child-one>
  • script
    methods:{
        /*定义方法*/
        showMsg () {
            alert('i am your father')
        }
    },

子组件ChildOne.vue

  • template
    <div>接收到父亲传来的消息:{{msgToChild}}div>
    
    <button @click="needFatherMethod">place click mebutton>
  • script
    props:{
        /*接收方法*/
        methodToChild:{
            type:Function
        }
    },
    methods:{
        /*触发方法*/
        needFatherMethod () {
            this.$emit('methodToChild')
        }
    }
  • 这个时候我们运行项目,点击按钮,发现,我们可以触发父组件的方法了
    在这里插入图片描述

1.3 $parent获取方法和属性

通过$parent来获取父组件的实例,从而获取父组件的属性和方法
子组件ChildOne.vue

  • template
    
    <button @click="$parentMethod">place $parentbutton>
  • script
    /*定义后去父组件实例的方法*/
    $parentMethod (){
        console.log(this.$parent._data.msg)//i am you father
        console.log(this.$parent.msg)//i am you father
        this.$parent.showMsg()//调用方法
    }

2. 子父通讯

2.1 属性传递

通过触发父组件的方法进行传递数据

  • 这等同于父 ===> 子 传递方法,方法的参数就是子组件的数据,emit的第二个参数就是父组件想要的数据
  • 缺点
    1. 需要一定的触发条件
    2. 不是响应式数据
    3. 一般触发条件只能在子组件,因为要得到的是子组件的数据(比如说在父函数定义一个方法通过这种方式来的到子组件数据,似乎比较困难。但是可以通过生命周期函数在子组件触发来传递数据)
      父组件Parent.vue
  • template
<div>接收到子组件传来的消息: {{childMsg}}div>

<child-one @getChildMsg="getChildMsg" :msgToChild="msg" @methodToChild="showMsg">child-one>
  • script
    data () {
        return {
            childMsg:''
        }
    },
    /*1.定义得到子组件数据的方法,触发条件只能在子组件
    * 2.在data中定义一个属性来保存子组件传递过来的数据
    * */
    getChildMsg (childMsg){
        this.childMsg = childMsg
    },

子组件ChildOne.vue

  • template

 <button @click="setParentMsg">place send parent msgbutton>
  • script
    data (){
        return {
            /*子组件数据*/
            msg:'i am your child'
        }
    },
   /*触发父组件的方法,并传递参数*/
   setParentMsg (){
       this.$emit('getChildMsg',this.msg)
   },

Vue组件之间的通讯方式_第2张图片

2.2 通过$refs主动获取子组件方法和属性

通过ref得到子组件的实例,进而得到子组件的方法和属性
父组件Parent.vue

  • template
<button @click="getMyChildMsgAndMethod">作为父亲,我要主动拿到孩子的信息button>
<div>这是孩子的信息: {{childMsg}}div>
 
 <child-one ref="myChild" @getChildMsg="getChildMsg" :msgToChild="msg" @methodToChild="showMsg">child-one>
  • script
    data () {
        return {
            childMsg:''
        }
    },
    /*得到子组件的方法和属性*/
    getMyChildMsgAndMethod (){
        this.childMsg = this.$refs.myChild.msg
        this.$refs.myChild.methodToParent()
    },

子组件ChildOne.vue

  • script
   /*父亲调用的方法*/
   methodToParent (){
     alert('i am you child')
   },
  • 当我们运行项目点击之后,我们就会得到了孩子的信息
    在这里插入图片描述

2.3 通过$children主动获取子组件方法和属性

通过this.$children得到的是一个子组件实例的数组

  • 除此之外,他的用法几乎和$refs相同
    父组件Parent.vue
  • template
   <button @click="$childrenMsg">$children得到孩子信息button>
   <div>这是孩子的信息: {{childMsg}}div>
  • script
    $childrenMsg (){
        /*this.$children得到是一个数组*/
        const child = this.$children[0]
        this.childMsg = child.msg
        child.methodToParent()
    },
  • 当我们运行项目之后再次点击按钮,就能得到孩子信息
    在这里插入图片描述

3. 兄弟通讯

3.1 通过共同的父亲进行传递信息

父组件只充当邮递员的角色

  • 他所利用的就是,父子和子父之间的通讯,两者的结合
  1. components文件夹下,新建ChildTwo.vue文件,代码如下

子组件ChildTwo.vue

  • template
<template>
    <div>
        <h1>ChildTwoh1>
        <div>{{commonMsg}}div>
    div>
template>
  • script
    export default {
        props:['common-msg'],
        name: "ChildTwo",
    }

子组件ChildOne.vue

  • template
  
  <button @click="setBrotherMsg">place send brother msgbutton>
  • script
    data (){
        return {
            /*定义数据*/
            commonMsg:'i love you ,my brother'
        }
    },
    props:{
    //接收父亲传来的方法,主要用于拿到此组件的数据
	  poster:{
	      type:Function
	  },
    },
     /*调用方法传递数据*/
    setBrotherMsg (){
        this.$emit('poster',this.commonMsg)
    },

父组件Parent.vue

  • template
   
   <child-one @poster="poster" ref="myChild" @getChildMsg="getChildMsg" :msgToChild="msg" @methodToChild="showMsg">child-one>
   
   <child-two :common-msg="commonMsg">child-two>
  • script
    data () {
        return {
        	//定义保存数据的变量
            commonMsg:''
        }
    },
    methods:{
        /*定义拿到数据的方法*/
        poster (commonMsg){
            this.commonMsg = commonMsg
        },
    }
  • 当我们把上面的代码写完,并运行之后,就会发现兄弟之间就可以拿到数据了
    Vue组件之间的通讯方式_第3张图片

3.2 通过event bus通讯

EventBus相当于全局的$emit,$on

  • 我们需要把它放到一个所有组件都能看得到的地方
    • 在这里我们就在src下新建了一个utils的文件夹,然后在这个文件夹中新建event-bus.js的文件,文件的内容如下
import Vue from 'vue'
/*EventBus就是一个vue的实例,我们可以通过他来调用Vue的实例方法*/
export const EventBus = new Vue()
/*当然,你也可以将它在入口文件上加入到原形中
* Vue.prototype.$EventBus = new Vue()
* 使用的时候直接就可以 this.$EventBus
* */
  • 写完上面代码之后我们就可以使用EventBus.$emitEventBus.$on来进行全局触发绑定事件了
  • 因为我们需要在兄弟组件之间通讯,我们只需要操作兄弟组件就可以了

兄弟组件ChildOne.vue

  • template
 <button @click="busBrotherMsg">send brother msg by busbutton>
  • script
   methods: {
       /*使用EventBus出发事件*/
       busBrotherMsg (){
           EventBus.$emit('busSendMsg',this.commonMsg)
       },
    }

兄弟组件ChildTwo.vue

  • template
        <div>EventBus传来的消息:{{busMsg}}div>
  • script
    data(){
        return {
            busMsg:''
        }
    },
            /*在生命周期函数中绑定事件*/
    mounted() {
        /*使用EventBus绑定事件*/
        EventBus.$on('busSendMsg',(busMsg) => {
            this.busMsg = busMsg
        })
    }
  • 当我们把所有的代码写好的时候,点击按钮就会发现,兄弟组件可以通讯了
    Vue组件之间的通讯方式_第4张图片

3.3 通过PubSub通讯

PubSub是一个包,专门用于组件之间的通讯

  • 使用PubSub.subsribe()订阅(注册)事件
  • 使用PubSub.publish()触发事件
  • 他与event-bus的使用差不多,只是参数略有不同,绑定事件的第一个参数必须传(请看下面的例题)
  • 一般在React中用的较多

使用

  1. 下载
npm install pubsub-js --save
  1. ChildOne.vue引入

兄弟组件ChildOne.vue

  • template
<button @click="pubsubBrotherMsg">send brother msg by pubsubbutton>
  • script
import PubSub from 'pubsub-js'
	methods: {
	   pubsubBrotherMsg (){
	       PubSub.subscribe('pubsubMsg',this.commonMsg)
	   },
	}
  1. ChildTwo.vue引入

兄弟组件ChildTwo.vue

  • template
<div>PubSub传来的消息:{{pubsubMsg}}div>
  • script
import PubSub from 'pubsub-js'
   data(){
       return {
           pubsubMsg:''
       }
   },
 mounted() {
 	/*msg:回调函数第一个参数,必须传*/
	  PubSub.subscribe('pubsubMsg',(msg,data) => {
	      this.pubsubMsg = data
	  } )
  }
  • 当写完代码,项目运行后,点击按钮,就会发现兄弟间的组件可以通讯了

3.4 通过Vuex通讯

Vuex是一个集中式的状态管理

  • 在这里就不多做介绍了,Vue全家同种必须掌握的知识点,有时间会写一篇与Vuex有关的博客。

你可能感兴趣的:(Vue项目,vue,js,javascript)