Vue组件通信

Vue组件通信

1. 父子组件通信

  • props $emit

    props[父组件给子组件传递信息,子组件通过props绑定某个属性,例如title,然后父组件给title赋值,子组件通过{{title}}来显示从父组件那里获得的信息]

<template>
 <div>
    <h1>我是子组件</h1>
    <h2>{{title}}</h2>
</div>
</template>

<script>
export default {
 props:['title']
}
</script>

<style>

</style>
 <!--子组件-->
<template>
  <div id="app">
      <h1>我是父组件</h1>
      <Child :title="msg"></Child>
  </div>
</template>
<script>

import Child from './Child.vue';
export default{
   name:'App',
  components:{
      Child
  },
  data(){
    return{
      msg:'123456',
    }
  }
}
</script>

<style lang="less">

</style>
 <!--父组件-->

在这里插入图片描述

$ e m i t [ 子 组 件 给 父 组 件 传 递 信 息 v m . emit[子组件给父组件传递信息 vm. emit[vm.$emit( event, arg )
e m i t 绑 定 一 个 自 定 义 事 件 e v e n t , 当 这 个 这 个 语 句 被 执 行 到 的 时 候 , 就 会 将 参 数 a r g 传 递 给 父 组 件 , 父 组 件 通 过 @ e v e n t 监 听 并 接 收 参 数 。 以 下 面 的 为 例 : 子 组 件 使 用 emit 绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件,父组件通过@event监听并接收参数。 以下面的为例:子组件使用 emiteventarg@event使emit定义一个事件’to-parent’,携带的参数为’我是子组件从过来的信息’,父组件中通过@to-parent监听并接收传过来的参数’我是子组件从过来的信息’,通过处理函数将传过来的参数赋值给msg,再通过{{msg}}显示出来]

   <template>
     <h1>子组件</h1>
   </template>
   
   <script>
   export default {
    mounted:function(){
        this.$emit('to-parent','我是子组件从过来的信息')
    }
   }
   </script>
   
   <style>
   
   </style>
   <!--子组件-->
   ```
   <template>
     <h1>父组件</h1>
     <h2>{{msg}}</h2>
     <child @to-parent="handleToParent"></child>
   </template>
   
   <script>
   import child from './Child.vue'
   export default {
     components: { 
         child 
         },
     data(){
         return{
             msg:''
         }
     } ,
     methods:{
         handleToParent(msg){
             this.msg=msg
         }
     }   
   }
   </script>
   
   <style>
   
   </style>
   <!--父组件-->
   ```
  • ref 元素或子组件注册引用信息

  • $refs 获取通过ref注册的引用

    ref[父组件给子组件传递信息,
    如果ref用在子组件上,指向的是组件实例,可以理解为对子组件的索引,通过$ref可能获取到在子组件里定义的属性和方法。
    如果ref在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,通过$ref可能获取到该DOM 的属性集合,轻松访问到DOM元素,作用与JQ选择器类似。
    以下面为例:在父组件中通过ref='ch'将子组件child的实例指给$ref并且通过.ch.getMessage()调用到子组件的getMessage方法,将参数传递给子组件。]
    
    <template>
      <h1>父组件</h1>
      <h2>{{msg}}</h2>
      <child  ref="ch"></child>
    </template>
    
    <script>
    import child from './Child.vue'
    export default {
      components: { 
          child 
          },
      data(){
          return{
              msg:''
          }
      } ,
      mounted:function(){
          this.$refs.ch.getMessage("我是父组件传过来的")
      }
      }
    </script>
    
    <style>
    
    </style>
    <!--父组件-->
    
    <template>
      <h1>子组件</h1>
     <h2>{{message}}</h2>
    </template>
    
    <script>
    export default {
        data(){
          return{
              message:""
          }
        },
        methods:{
            getMessage(msg){
                this.message=msg;
            }
        }
    }
    </script>
    
    <style>
    
    </style>
    <!--子组件-->
    
  • $parent获取当前组件的父组件实例

  • $children获取当前组件的子组件实例

    vue2中使用,但是vue3中已作废
    
<template>
 <div>
    <h1>我是子组件</h1>
    <h2>{{msg}}</h2>
</div>
</template>

<script>
export default {
    data(){
        return{
            msg:'hello',
        };
    },
    methods:{
       fun(){
           console.log('我是子组件'+this.$parent.msgP);
       }
    },
    mounted(){
        this.fun();
    }
}
</script>

<style>

</style>
    <!--子组件-->
<template>
  <div id="app">
      <h1>我是父组件</h1>
      <Child></Child>
  </div>
</template>
<script>

import Child from './Child.vue';
export default{
   name:'App',
  components:{
      Child
  },
  data(){
    return{
      msgP:'123456',
    }
  },
  methods:{
     fun(){
       console.log('我是父组件'+this.$children[0].msg);

     }
  },
  mounted(){
    this.fun();
  }
}
</script>

<style lang="less">

</style>
   <!--父组件-->

在这里插入图片描述

  1. 多层级父子组件通信

    • provide、inject
      多层级通信 爷爷到孙子-传值 provide-inject
      provide 选项应该是一个对象或返回一个对象的函数。
      inject 选项应该是:一个字符串数组,或一个对象。
      以下面为例:父组件通过provide将test的值传递给孙组件,孙组件通过inject来获取值,从而完成多层级通信。
   <template>
       <h1>父组件</h1>
       <child></child>
     </template>
     
     <script>
     import child from './Child.vue'
     export default {
       components: { 
           child 
           },
       provide:{
          test:"父组件->孙组件"
       }
       }
     </script>
     
     <style>
     
     </style>
     <!--父组件-->
 <template>
       <h1>子组件</h1>
       <grandson></grandson>
     </template>
     
     <script>
     import grandson from './Grandson.vue'
     export default {
         components:{
             grandson
         }
     }
     </script>
     
     <style>
     
     </style>
     <!--子组件-->
<template>
       <h1>孙组件</h1>
       <h2>{{test}}</h2>
     </template>
     
     <script>
     export default {
        inject:["test"]
     }
     </script>
     
     <style>
     
     </style>
     <!--孙组件-->
  • $attrs、 $listeners

     $attrs:   
        正常情况下:父组件通过v-bind绑定一个数据传递给子组件,子组件通过props接收到就可以在子组件的html中使用了。但是,如果父组件v-bind传递给子组件,子组件没有用props接收呢?
        注意:这个时候,父组件传递过来的数据就会被挂载(赋值)到这个子组件自带的对象$attrs上面,所以:
        $attrs就是一个容器对象,这个容器对象会存放:父组件传过来的且子组件未使用props声明接收的数据 。
    爷组件传递给孙组件的逻辑流程
    其实,爷组件传递给孙组件的逻辑流程就是,通过爷组件首先传递给父组件,当然父组件不在props中接收,那么爷组件传递给父组件的数据就会存放到父组件的$attrs对象中里面了,然后,再通过v-bind="$attrs",再把这个$attr传递给孙组件,在孙组件中使用props就能接收到$attrs中的数据了,这样就实现了,祖孙之间的数据传递。
    
<template>
       <h1>父组件</h1>
       <child :msg="msg"></child>
     </template>
     
     <script>
     import child from './Child.vue'
     export default {
       components: { 
           child 
           },
        data() {
           return {
              msg:'我是父组件'
           }
       }   
       }
       
     </script>
     
     <style>
     
     </style>
     <!--父组件-->
 <template>
       <h1>子组件</h1>
       <h2>{{$attrs.msg}}</h2>
       <grandson v-bind="$attrs"></grandson>
     </template>
     
     <script>
     import grandson from './Grandson.vue'
     export default {
         components:{
             grandson
         }
     }
     </script>
     
     <style>
     
     </style>
     <!--子组件-->
 <template>
       <h1>孙组件</h1>
       <h2>{{msg}}</h2>
     </template>
     
     <script>
     export default {
        inheritAttrs: false,
        props:['msg']
     }
     </script>
     
     <style>
     
     </style>
     <!--孙组件-->
 $listeners
 使用$listeners可以实现孙组件的数据传递到父组件中去,逻辑的话,也是用在中间的桥梁子组件上面去,我的理解就是$listeners可以将孙组件emit的方法通知到父组件。
 第一步,在中间的子组件中加上$listenners
  <Son v-on="$listeners" @toGp="handleFun"></Son>
 第二步,父组件中定义事件方法
<template>
  <div id="app">
      <h1>我是父组件</h1>
      <h2>{{msgP}}</h2>
      <Child @toGp="handleFun"></Child>
  </div>
</template>
<script>

import Child from './Child.vue';
export default{
   name:'App',
  components:{
      Child
  },
  data(){
    return{
      msgP:'123456',
    }
  },
  methods:{
    handleFun(val){
      this.msgP=val;
    }
  },
}
</script>

<style lang="less">

</style>
 <!--父组件-->
 第三步,孙组件去触发事件方法即可
<template>
<div>
    <h1>我是孙组件</h1>
  <h2>{{msg}}</h2>
</div>
</template>

<script>
export default {
  data(){
      return{
          msg:'hello'
      }
  },
  methods:{
      p(){
          this.$emit('toGp',this.msg);
      }
  },
  mounted(){
      this.p();
  }
}
</script>

<style>

</style>
 <!--孙组件-->
<template>
 <div>
    <h1>我是子组件</h1>
     <h2>{{msg1}}</h2>
    <Son v-on="$listeners" @toGp="handleFun"></Son>
</div>
</template>

<script>
import Son from './Son.vue';
export default {
    components:{
       Son
    },
    data(){
        return{
            msg1:'hello',
        };
    },
    methods:{
         handleFun(val){
          this.msg1=val;
    }
    },
 
}
</script>

<style>

</style>

在这里插入图片描述

  1. 非关系组件通信

//main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus=this;
  }
}).$mount('#app')

<template>
  <div id="app">
      <h1>我是父组件</h1>
      <Child></Child>
  </div>
</template>
<script>

import Child from './Child.vue';
export default{
   name:'App',
  components:{
      Child
  },
  methods:{
     p(){
       this.$bus.$emit('myhub','hello');
     }
    
  },
  mounted(){
    this.p();
  }
}

</script>

<style lang="less">

</style>
     <!--父组件-->
<template>
 <div>
    <h1>我是子组件</h1>
     <h2>{{msg1}}</h2>
</div>
</template>

<script>
import Son from './Son.vue';
export default {
    components:{
       Son
    },
    data(){
        return{
            msg1:'',
        };
    },
    methods:{
         f(){
             this.$bus.$on('myhub',data=>{
                 this.msg1=data;
             })
         }
    },
   mounted(){
       this.f();
   }
 
}
</script>

<style>

</style>
   <!--子组件-->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值