精讲vue中父子组件,子父组件,同级组件的通信

接触vue也差不多半年有余了,有些东西还感觉有点模糊,现在又学一遍好好总结一下,夯实基础
直接进入主题

1,父子组件通信

父子组件通信是这三种通信,最简单易懂的,就是在我们定义组件的时候使用props写入需要传入的数据,在使用组件的时候传入即可,这里需要注意的是vue中对props有 类型检查功能,建议在实际开发中使用类型检查功能,减少bug出现的几率

                     props:{
                       name:{
                            type:String,
                            default:'这是默认值’
                              },
                            age:{
                               type: Number,
                               default:18
                                }
                         }

接下来看一个栗子

<body>
    <div id="app">
        <alert message="帅朗朗"></alert>
    </div>
    <script>
       var app = new Vue({
            el:'#app',
            components:{
               alert:{
                   template:'<button @click="onclick()">点我</button>',
                   props:{
                       message:{
                           type:String,
                           default:'我是默认值'
                       }
                   },
                   methods:{
                       onclick:function(){
                         return  alert(this.message)
                       }
                   }
               }
            }
        })
    </script>
</body>

这是一个弹出框组件,当我们使用组件的时候,传入message的值,不传入就是用默认值。

2,子父组件的通信

子父组件通信,顾名思义,是子组件向父组件通信(喊话),使用vue中的$emit方法实现,子组件使用$emit触发一个事件,在父组件中监听此事件即可。

<body>
    <div id="app">
         <balance></balance>
    </div>
    <script>
       Vue.component('balance',{
           template:`
            <div>
                <show @show-balance="show_balance"></show> 
                <div v-if="show">你的余额:99¥</div>
            </div>
           `,
           data(){
               return {
                   show:false
               }
           },
           methods:{
            show_balance(data){
               this.show=true
               show_balance
            }
           },
       })
       Vue.component('show',{
           template:`
           <button @click="on_click">显示余额</button>
           `,
           methods: {
               on_click(){
                   this.$emit('show-balance',{name:'帅朗朗'})
               }
           }
       })
       var app = new Vue({
            el:'#app',
        })
    </script>
</body>

在这个栗子中,我们注册了一个父组件balance,显示余额的功能,和一个子组件show,控制是否把余额显示出来的功能,当触发show组件的on_click()方法时,就会触发show-balance方法,通过父组件监听了show-balance方法,从而触发了show_balance方法(使show)可通过传入data参数,获取子组件传入的数据({name:'帅朗朗'}),把余额显示出来。
在这里大家注意一个细节我们在写show_balance方法写成show_balance()和show_balance的区别是不加夸号默认是this.$emit传过来的数据,加夸号是自己自定义的数据,就接收不到子组件传过来的数据。

3,同级组件的通信

同级组件之间的通讯需要一个bus总线,先说一下什么是事件总线,其实就是订阅发布者模式;比如有一个bus对象,这个对象上有两个方法,一个是on(监听,也就是订阅),一个是emit(触发,也就是发布),我们通过on方法去监听某个事件,再用emit去触发这个事件,同时调用on中的回调函数,这样就完成了一次事件触发;
这是一种设计模式,和语言没有关系。

vue自带事件总线的缺点
我们都知道在vue被实例化之后,他就具备了充当事件总线对象的能力,在他上面挂了两个方法,是$emit$on
而vue文档说的很明白,$emit会触发当前实例上的事件,附加参数都会传给监听器回调;由于在实际工作中,我们都是以组件的形式开发,每个组件就是一个实例;
所以利用vue自带的总线能力有很大的局限性,最多只能从子组件触发到父组件中,而不能在非父子组件之间传值;
所以这时,我们就需要有一个全局的事件总线对象,让我们挂载监听事件和触发事件;

 Vue.prototype.bus = new Vue()  //在Vue的原型上挂一个bus

这样我们就可以在整个项目中使用事件总线bus了,

<body>
    <div id="app">
       <boy></boy>
       <girl></girl>
    </div>
    <script>
      Vue.prototype.bus=new Vue()         //vue同级组件的通信需要事件总线来调度事件,
        Vue.component('girl',{
            template:
               `<div>
                 <div>the boy say:{{this.message}}</div>
                </div>`,
              data(){
                  return {
                    message:"default"
                  }
              },
              mounted () {
                this.getMessage()
              },
              methods:{
               getMessage(){
                    this.bus.$on('appointment',(data)=>{
                        this.message=data
                        console.log(this.message)
                    })      
                      console.log(this.message)
               }
              }
        })
        Vue.component('boy',{
            template:`<div>
                <button @click="shout">boy</button>
                </div>`,
                methods: {
                    shout(){
                     this.bus.$emit('appointment','今天6点半老地方见')
                    }
                }
        })
       var app = new Vue({
            el:'#app',
       })
    </script>
</body>

在上面这个栗子中,使用在vue的prototype上挂一个bus,也是一个Vue的实例,这样girl和boy组件都可以使用bus了,我们现在boy组件中用this.bus.$emit触发一个appointment方法,并且在传入数据“今天6点半老地方见”.然后在girl组件通过this.bus.$on监听这个事件,产生一个回调,获取boy穿过来的参数。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容