Vue组件之间的通信方式(个人理解)

  1. props(父传子)
   //父组件 parent.vue
   <template>
      //子组件
      <child-com :num="num" :str="str" :obj="obj" :func="func" />
   </tempalte>
   //引入子组件
   import ChildCom from './components/child';
   export default{
     components:{ChildCom},
     data(){
       return {
           num:25,
           str:'这是一个字符串类型的父组件传递的值',
           obj:{
               attr:'一个对象中的属性值'
           }
       }
     },
     methods:{
       func(){
           console.log('这是一个父组件的方法,可以由子组件通过props方式调用');
       }
     }
   }
   
   //子组件 child.vue
   export default{
       props:{
           num:{
               type:Number//num的类型为---数字类型
           },
           str:{
               type:String,//str的类型为---字符串类型
               default:'hello default value'//str的默认值
           },
           obj:{
               type:Object,//obj的类型为---对象类型
               reqired:true//是否必传的参数,布尔值true:必须传这个参数 ,默认为false:不是必传
           },
           func:{
               type:Function, //func的类型为---函数
               default(){   //不传递时默认值
                   return ()=>{}
               }
           }
       },
       data(){
         return{}
       },
       mounted(){
         console.log(this.num);
         //控制台输出:25
         console.log(this.str);
         //控制台输出:这是一个字符串类型的父组件传递的值
         console.log(this.obj);
         //控制台输出:{attr:'一个对象中的属性值'}
         this.func();
         //调用parent的func方法
         //控制台输出:这是一个父组件的方法,可以由子组件通过props方式调用
       }
   }
   
  1. v-on/this.$emit(‘方法名’,‘参数’);(父传子,子通过调用父传来的方法回传参数)
//(父传子,子通过调用父传来的方法回传参数)
//父组件: @childMethod="parentMethod"  
//子组件: this.$emit('方法名',参数) 
//childMethod:child子组件中this.$emit('childMethod',参数)
//parentMethod:parent父组件中的要被子组件调用的方法名

   //父组件 parent.vue
   <template>
      //子组件
      <child-com :num="num" :str="str" :obj="obj" @func="func" />
   </tempalte>
   //引入子组件
   import ChildCom from './components/child';
   export default{
     components:{ChildCom},
     data(){
       return {
           num:25,
           str:'这是一个字符串类型的父组件传递的值',
           obj:{
               attr:'一个对象中的属性值'
           }
       }
     },
     methods:{
       func(arguments){
           console.log('这是一个父组件的方法,可以由子组件通过props方式调用',arguments);
       }
     }
   }
   
   //子组件 child.vue
   export default{
       props:{
           num:{
               type:Number//num的类型为---数字类型
           },
           str:{
               type:String,//str的类型为---字符串类型
               default:'hello default value'//str的默认值
           },
           obj:{
               type:Object,//obj的类型为---对象类型
               reqired:true//是否必传的参数,布尔值true:必须传这个参数 ,默认为false:不是必传
           }
       },
       data(){
         return{}
       },
       mounted(){
         console.log(this.num);
         //控制台输出:25
         console.log(this.str);
         //控制台输出:这是一个字符串类型的父组件传递的值
         console.log(this.obj);
         //控制台输出:{attr:'一个对象中的属性值'}
         this.$emit('func',参数);
         //调用parent的func方法
         //控制台输出:这是一个父组件的方法,可以由子组件通过props方式调用,参数
       }
   }
   
  1. this.$refs.child.method(arguments);(父传子)
//child:为子组件ref注册的名字,可自行命名
//method:为子组件中的方法名

   //父组件 parent.vue
   <template>
      //子组件
      <child-com ref="child" />
   </tempalte>
   //引入子组件
   import ChildCom from './components/child';
   export default{
     components:{ChildCom},
     data(){
         return{}
     }
     methods:{
       func(){
         this.$refs.child.childMethod();
         //控制台输出:我是子组件的方法,父组件通过this.$refs.child.childMethod()调用
       }
     }
   }
   
   //子组件 child.vue
   export default{
     props:{},
     data(){
       return{}
     },
     mounted(){},
     methods:{
       childMethod(){
         console.log('我是子组件的方法,父组件通过this.$refs.child.childMethod()调用');
       }
     }
   }
  1. this. p a r e n t . parent. parent.parent.func(arguments);(子传父)
//父组件的fun方法

   //父组件 parent.vue
   <template>
      //子组件
      <child-com  />
   </tempalte>
   //引入子组件
   import ChildCom from './components/child';
   export default{
     components:{ChildCom},
     data(){
       return {}
     },
     methods:{
       func(arguments){
           console.log('这是一个父组件的方法,可以由子组件通过this.$parent.$parent(参数)方式调用',arguments);
       }
     }
   }
   
   //子组件 child.vue
   export default{
       props:{ },
       data(){
         return{}
       },
       mounted(){
       this.$parent.$parent.func('参数');
         //调用parent的func方法
         //控制台输出:这是一个父组件的方法,可以由子组件通过this.$parent.$parent(参数)方式调用,参数
       }
   }
   
  1. this.$attrs:里面包含所有父组件中不作为 prop传递的属性。可以进行跨级的参数传递
//(父传子---属性)
//可修改this.$atrrs里的属性值

  //父组件 parent.vue
  <template>
    <child-com str="这是一个不通过prop传递的字符串" :strProp="strProp" />
  </template>
  export default {
    data(){
      return {
          strProp:"这是一个通过prop传递的字符串"
      }
    },
  }
  
  //子组件 child.vue
  <tempalte>
    <grand-child v-bind="$attrs" /> //针对向下级组件传递
  </temaplate>
  
  import GrandChildCom from './grandchild';
  
  export default {
    components:{GrandChildCom},
    props:{
        strProp:{
            type:String,
            default:''
        }
    },
    data(){
        return {}
    },
    mounted(){
        console.log(this.$atrrs);//{str:'这是一个不通过prop传递的字符串'}
        console.log(this.strProp);//这是一个通过prop传递的字符串
    }
  }
  
  //孙子组件GrandChild.vue
  export default {
    props:{
        strProp:{
            type:String,
            default:''
        }
    },
    data(){
        return {}
    },
    mounted(){
        console.log(this.$atrrs);//{str:'这是一个不通过prop传递的字符串'}
        console.log(this.strProp);//这是一个通过prop传递的字符串
    }
  }
  1. this.$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器
//(父传子---方法,子通过调用父传来的方法回传参数)
//this.$listeners

  //父组件 parent.vue
  <template>
    <child-com @handleUpdate="handleUpdate" @handleAdd.native="handleAdd" />
  </template>
  export default {
    data(){
      return {}
    },
    methods:{
        handleUpdate(val){
            console.log('这是handleUpdate的日志',val);
        },
        handleAdd(){
            console.log('这是handleAdd的日志');
        },
    }
  }
  
  //子组件 child.vue
  <tempalte>
    <grand-child-com v-on="$listeners" /> //针对向下级组件传递
  </temaplate>
  
  import GrandChildCom from './grandchild';
  
  export default {
    components:{GrandChildCom},
    props:{},
    data(){
        return {}
    },
    mounted(){
        console.log(this.$listeners);//{handleUpdate:f}
        console.log(this.$listeners.handleUpdate('child调用的'));//这是handleUpdate的日志,child调用的
    }
  }
  
  //孙子组件GrandChild.vue
  export default {
    props:{
        strProp:{
            type:String,
            default:''
        }
    },
    data(){
        return {}
    },
    mounted(){
        console.log(this.$listeners);//{handleUpdate:f}
        console.log(this.$listeners.handleUpdate('grandChild调用的'));//这是handleUpdate的日志,grandChild调用的
    }
  }
  1. provide/inject(选项 / 组合):允许一个祖先组件向其所有子孙后代注入一个依赖,可以注入属性和方法,从而实现跨级父子组件通信
//(父传子---依赖,子通过调用父传来的方法回传参数)
// provide/inject

  //父组件 parent.vue
  <template>
    <child-com  />
  </template>
  export default {
    data(){
      return {
          name:'Hello Xiaoer'
      }
    },
    provide() {
      return {
        provideName: {
          name: this.name,
          change: (val) => {
            console.log( val )
          }
        }
      }
    }
  }
  
  //子组件 child.vue
  <tempalte>
    <grand-child-com  /> //针对向下级组件传递
  </temaplate>
  
  import GrandChildCom from './grandchild';
  
  export default {
    components:{GrandChildCom},
    props:{},
    data(){
        return {}
    },
    inject: ['provideName'],
    mounted(){
        console.log(this.provideName.name);//控制台输出:Hello Xiaoer
        this.provideName.change('变化函数');//控制台输出:变化函数
    },
  }
  
  //孙子组件GrandChild.vue
  export default {
    props:{},
    data(){
        return {}
    },
    inject: ['provideName'],
    mounted(){
        console.log(this.provideName.name);//控制台输出:Hello Xiaoer
        this.provideName.change('变化函数');//控制台输出:变化函数
    },
  }
  1. EventBus:(第三方库)甚至任意2个组件间通信(任意组件)
[github地址](https://github.com/krasimir/EventBus)
//通过导出一个 Vue 实例,然后再需要的地方引入:
    // eventBus.js 
    import Vue from 'vue'export 
    const EventBus = new Vue()

    //使用 EventBus 订阅和发布消息:
    import {EventBus} from '../utils/eventBus.js'

    // 订阅消息(接受更新后需要做点什么的组件)
    EventBus.$on('update', val => {})

    // 发布消息(负责更新的组件)
    EventBus.$emit('update', '更新信息')
//在main.js中初始化一个全局的事件:
    // main.js
    Vue.prototype.$eventBus = new Vue()

    //index.vue 
    // 订阅消息(接受更新后需要做点什么的组件)
    this.$eventBus.$on('update', val => {})
    // 发布消息(负责更新的组件)
    this.$eventBus.$emit('update', '更新信息')

//移除事件监听
    this.$eventBus.$off('update', {})
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐