我们通常会把整个页面被分成小组件,这些组件有自己的功能和 UI。 有时,我们需要一种方法来在这些组件之间进行通信。
我们可以使用 Vuex(状态管理工具)来存储数据并跨组件使用。 但有时,我们需要一种方法将数据从一个组件发送到另一个组件,而无需使用 Vuex 存储。
请看下面:

1、使用Props (父组件通信子组件)

2、使用Events 事件(子组件通信父组件)

3、使用Event Bus 事件总线(父通信子,子通信父)

4、使用provide/inject 提供和注入对(父组件通信子组件)

5、使用this.$refs (子组件通信父组件)

第一种:Props

[父到子]使用Props可以将我们需要传输的数据从父组件传递到子组件。下面我们将使用props从parent.vue发送数据到child.vue
<!-- child.vue 代码 -->
<template>
  <div>
    {{message}}
  </div>
</template>

<script>
export default {
  name: "child",
  props: ['message'] // 定义一个名为message的变量,在页面进行渲染
}
</script>
<!-- parent 组件 代码 -->
<template>
  <div>
    <!-- 使用子组件 child,绑定一个参数,参数名为message,值为当前组件变量名为message的值-->
    <child :message="message"/>  
  </div>
</template>

<script>
import Child from "./child"; <!-- 使用子组件 -->

export default {
  name: "parent",
  components: {Child},
  data() {
    return {
      message: '我是父类的数据'
    }
  }
}
</script>

 

第二种:Events

[子到父]通过子组件触发事件将数据发送到父组件,父组件使用v-on进行捕获,捕获时需要和发送事件同名,还可以检索参数this.$emit(‘事件名’, args1, args2, args3,…) 就是一种触发事件的方法

<!-- child 子组件 代码 -->
<template>
  <div>
    <div @click="sendMessageToParent"></div>
  </div>
</template>

<script>
export default {
  name: "child",
  message: "数据",
  methods: {
    sendMessageToParent() {
      // 点击后触发一个事件  事件名为childSuccess,参数为message
      this.$emit("childSuccess", this.message);
    }
  }
}
</script>
<!-- parent 父组件 代码 -->
<template>
  <div>
    <!-- 使用子组件 监听事件名为childSuccess的事件,一旦监听到后触发getData方法-->
    <child @childSuccess="getData"/>
  </div>
</template>

<script>
import Child from "./child";
export default {
  name: "parent",
  components: {Child},
  methods: {
    getData(_val) {
      // _val 就是子组件的事件携带的参数
      console.log(_val)
    }
  }
}
</script>

第三种:Event Bus
[父到子,子到父]当两个需要互相通信的组件不存在父子关系的时候,需要手动去监听组件上的事件的时候,就可以使用此方法(事件总线)。所以事件总线用于在任何两个组件之间进行通信(组件不需要具有父子关系)。操作方法: 在一个组件使用this.r o o t . root.root.emit(‘事件名’,args1,args2,args3,…); 在另一个组件中使用this.r o o t . root.root.on(‘相同的事件名’,args1,args2,args3,…)

<!--component_one 组件 监听事件-->
<template>
</template>

<script>
export default {
  name: "component_one",

  mounted() {
    this.$root.$on("success", (msg) => {
      console.log(msg)
    })
  }
}
</script>

<!--component_two组件 发布事件-->
<template>
  <div @click="sendMessageToComponentOne">
    <router-link to="/component_one">点我!</router-link>
  </div>
</template>

<script>
export default {
  name: "component_two",
  methods: {
    sendMessageToComponentOne() {
      let msg = '你好呀!';
      this.$root.$emit("success",msg)
    }
  }
}
</script>

第四种:provide/inject

[父到子]此类主要是用于更深层嵌套组件的结构,使用这种方式可以更快捷更方便,且子孙后代后可以使用inject
<!-- parent 父组件 -->
<template>
  <child />
</template>

<script>
import Child from "./child";
export default {
  name: "parent",
  components: {Child},
  provide() {
    return {"eventName": "参数"}
  }
}
</script>
<!-- child 子组件 -->
<template>
  <div>{{eventName}}</div>
</template>

<script>
export default {
  name: "child",
  inject: ['eventName'],

}
</script>

第五种:this.$refs

[子到父]一般都不推荐使用此种方法进行数据通信。 使用这种方式的时候,我们需要为子组件一个引用id
<!-- child 子组件 -->
<template>
</template>

<script>
export default {
  name: "child",
  data() {
    return {
      value: '你好呀!'
    }
  }
}
</script>
<!-- parent 父组件 -->
<template>
  <child ref="child"/>
</template>

<script>
import Child from "./child";
export default {
  name: "parent",
  components: {Child},

  data() {
    return {
      message: null
    }
  },

  mounted() {
    // 获取子组件上的value值
    this.message = this.$refs.child.value;
  }
}
</script>