请说一下vue的组件通信有哪些?

答:vue的组件通信分为3类:父子通讯,子父通讯,跨级通讯。父子通讯,父组件通过属性传值,子组件通过props接收,props接收时有两种写法,第一种是数组,第二种是对象,对象可以做参数的校验等。子父通讯,父组件传递一个函数给子组件,子组件通过调用父组件传递的函数来传递参数。跨级通讯,可以通过provide/inject$attrs$busvuex等实现。

为什么需要组件通讯?

vue是组件化开发,我们项目代码中的各个模块都是通过组件组合而成,而且组件之间的参数都会有相互依赖的关系,所以我们需要熟练掌握组件通讯

组件通讯的分类:

  • 父子组件
  • 同级组件
  • 跨域组件

    1、父子通讯:

    父组件向子组件Child传递参数:

  • attr1 静态传参

  • arr2 动态传参

    1. <template>
    2. <Child attr1="msg" :attr2="msg">this is header</Child>
    3. </template>
    4. <script>
    5. import Child from "./child";
    6. export default {
    7. name: 'Header',
    8. data(){
    9. return {
    10. msg:"12323"
    11. }
    12. },
    13. components:{
    14. Child
    15. }
    16. };
    17. </script>

    子组件:
    子组件通过props来获得父组件传递的参数

  • 数组 简单

  • 对象 完整
    1. <template>
    2. <div>这里是子组件</div>
    3. </template>
    4. <script>
    5. export default {
    6. name: 'Child',
    7. // props两种写法
    8. // props:["attr1","attr2"],
    9. props:{
    10. attr1:{
    11. type:"String|Number|Boolean|Null|Undefined|Array|Object|Function",
    12. default:"默认值",
    13. require: true|false
    14. }
    15. }
    16. };
    17. </script>

    子父通讯

    1. 子: this.$emit('事件名',"任意数据类型的值")
    2. 父:v-on:事件名="回掉函数"

父组件-子组件传递一个函数,子组件调用父组件传递过来的函数,传入参数,父组件传递的这个函数就可以通过回调形参,拿到子组件传递的参数

跨级通讯

  • Vue v2.2新增 provide/inject

父组件

  1. <template>
  2. <div></div>
  3. </template>
  4. <script>
  5. export default {
  6. provide:{
  7. key:val,
  8. ...
  9. }
  10. };
  11. </script>

子组件

  1. <template>
  2. <div></div>
  3. </template>
  4. <script>
  5. export default {
  6. name: "DialogFooot",
  7. inject:["key1",...],
  8. };
  9. </script>
  • Vue v2.4新增 $attrs

想要使用$attrs 在父组件中不可以通过props去定义
祖先组件:

  1. <template>
  2. <div>
  3. <Parent :key1="key1" :key2="key2" ...></Parent>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: "Origine",
  9. data(){
  10. return {
  11. key1:val1,
  12. key2:val2
  13. }
  14. }
  15. };
  16. </script>

父组件 - parent:

  1. <template>
  2. <div>
  3. // 父组件可以通过$attrs获得祖先组件中的数据
  4. // 不需要通过props去接受
  5. {{$attrs}}
  6. <Child v-bind="$attr"></Child>
  7. </div>
  8. </template>
  9. <script>
  10. export default {
  11. name: "Parent",
  12. inheritAttrs: false,
  13. };
  14. </script>

子组件:

  1. <template>
  2. <div>
  3. // 子组件需要获得父组件的参数,父组件通过v-bind将$attr绑定
  4. {{$attrs}}
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. name: "Child",
  10. inheritAttrs: false,
  11. mounted(){
  12. // js方式
  13. console.log(this.$attrs)
  14. }
  15. };
  16. </script>

EventHub & EventBus

由于vue原生支持发布、订阅模式,我们通过 new Vue() 创建新的实例。
utils/hub.js

  1. import Vue from 'vue';
  2. export default new Vue();

main.js

  1. import Vue from "vue";
  2. import App from "./App.vue";
  3. import router from "./router";
  4. Vue.config.productionTip = false;
  5. import EventHub form "@/utils/events"
  6. Vue.prototype.$eventHub = EventHub;
  7. new Vue({
  8. router,
  9. render: h => h(App),
  10. }).$mount("#app");
  1. 组件内部:
  2. 子:this.$eventhub.emit('eventname',callback);
  3. 父:this.$eventhub.$on('event',callback)

Vuex