Vue组件通信的7个方法

1.props和$emit

父组件向子组件传递数据是通过prop传递的,子组件传递数据给父组件是通过$emit触发事件来做到的

  Vue.component("child",{      data () {        return {          mymessage:this.message        }      },      template:`        <div>            <input type="text" v-model="mymessage" @input="setFather(mymessage)">          </div>      `,      props:{        message:String      },      methods:{        setFather (val){          this.$emit("getChildData",val)        }      }    })    Vue.component("parent",{      data:function () {        return {          messageFather:"儿子,我是你爸爸啊"        }      },      template:`        <div>          <p> this is parentcomponent!</p>          <child :message="messageFather" @getChildData="getChildData"></child>        </div>      `,      methods:{        getChildData(val){          console.log(val)        }      }    })    var app = new  Vue({      el:"#app",    })复制代码

2.$attrs和$listeners

第一种方式处理父子组件之间的数据传输有一个问题:如果父组件A下面有子组件B,组件B下面有组件C,这时如果组件A想传递数据给组件C怎么办呢? 如果采用第一种方法,我们必须让组件A通过prop传递消息给组件B,组件B在通过prop传递消息给组件C;要是组件A和组件C之间有更多的组件,那采用这种方式就很复杂了。Vue 2.4开始提供了$attrs和$listeners来解决这个问题,能够让组件A之间传递消息给组件C

  <script>    Vue.component("childs",{      data() {        return{          mymessages:"我可能要接受到来自我爷爷的消息"        }      },      template:`        <div>          <p>我是儿子的儿子</p>          <input type="text" v-model="$attrs.messageChilds" @input="getGrandChild($attrs.messageChilds)">          </div>      `,      methods:{        getGrandChild(val){          this.$emit("getGrandChild",val)        }      }    })    Vue.component("child",{      data () {        return {          mymessage:this.message        }      },      template:`        <div>            <input type="text" v-model="mymessage" @input="setFather(mymessage)">              <childs  v-bind="$attrs" v-on="$listeners"></childs>        </div>      `,      props:{        message:String      },      methods:{        setFather (val){          this.$emit("getChildData",val)        }      }    })    Vue.component("parent",{      data:function () {        return {          messageFather:"儿子,我是你爸爸啊",          messageGrandFather:"孙子我是你爸爸啊"        }      },      template:`        <div>          <p> this is parentcomponent!</p>          <child  :messageChilds="messageGrandFather" :message="messageFather" @getChildData="getChildData" @getGrandChild="getGrandChild"></child>        </div>      `,      methods:{        getChildData(val){          console.log(val)        },        getGrandChild(val){          console.log(val)        }      }    })    var app = new  Vue({      el:"#app",    })  </script>复制代码

此方法是通过想目标的子组件 绑定 v-bind="$attrs"  与 v-listeners; 而子组件过的数据为$.attrs的对象,数据为 $attrs.messageChild,实现数据的接受,而子组件传递给父组件则是通过$meit传递事件来向父组件传递相应的数据.

3. 中央事件总线

上面两种方式处理的都是父子组件之间的数据传递,而如果两个组件不是父子关系呢?这种情况下可以使用中央事件总线的方式。新建一个Vue事件bus对象,然后通过bus.$emit触发事件,bus.$on监听触发的事件。

  <script>    Vue.component("brotherb",{      data () {        return {          mymessageBrotherB:"我是brotherb",          brothera:''        }      },      template:`        <div>          <p>{{mymessageBrotherB}}</p>          <p>{{brothera}}</p>        </div>      `,      props:{        message:String,            },      mounted(){        bus.$on('globalEvent',(val)=>{         this.brothera=val       })      }    })    Vue.component("brothera",{      data:function () {        return {          messageBrotherA:"我是brotherA",          mymessage:"你好 ,brotherB"        }      },      template:`        <div>          <p>{{messageBrotherA}}</p>           <input type="text" v-model="mymessage" @input="passData(mymessage)">        </div>      `,      methods:{        passData(val){          bus.$emit("globalEvent",val)        }      }    })    //中央事件总线    const bus=new Vue();    const app = new Vue({      el:"#app",    })  </script>复制代码

首先我们或创建一个 bus实例, 父组件在mthods方法中,通过bus.$emit()中传递事事件携带参数,然后兄弟组件mounted钩子函数中 通过bus.$on()接受事件和方法.

4. provide和inject

父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。

<script>    Vue.component("child",{      inject:['for'],      data () {        return {          mymessage:"我是儿子",          messageFather:this.for        }      },      template:`        <div>          <p>{{mymessage}}</p>          {{messageFather}}        </div>      `,      mounted(){      }    })    Vue.component("parent",{      data:function () {        return {          mymessage:"我是父亲"        }      },      provide:{        for:"你好儿子啊"      },      template:`        <div>          <p>{{mymessage}}</p>           <child></child>        </div>      `,      methods:{             }    })    const app = new Vue({      el:"#app",    })  </script>复制代码

5. v-model

父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input',val)自动修改v-model绑定的值

  Vue.component("child",{      props:{        value:String      },      data () {        return {          mymessage:this.value,        }      },      template:`        <div>          <input  type="text" v-model="mymessage" @change="changeValue">        </div>      `,      mounted(){      },      methods:{        changeValue() {          this.$emit('input',this.mymessage)        }      }    })    Vue.component("parent",{      data:function () {        return {          message:"son",        }      },      template:`        <div>          <p>{{message}}</p>           <child v-model="message"></child>        </div>      `,      methods:{             }    })    const app = new Vue({      el:"#app",    })  </script>复制代码

6. $parent和$children

 <script>    Vue.component("child",{      data () {        return {          mymessage:"我是儿子",        }      },      template:`        <div>         <input type="text" v-model="mymessage" @change="changeParent">        </div>      `,      mounted(){      },      methods:{        changeParent () {          this.$parent.message=this.mymessage        }      }    })    Vue.component("parent",{      data:function () {        return {          message:"我是父亲",        }      },      template:`        <div>          <p>{{message}}</p>           <button @click="changeBtn">改变儿子</button>          <child></child>        </div>      `,      methods:{        changeBtn () {          this.$children[0].mymessage="hello"        }      }    })    const app = new Vue({      el:"#app",    })  </script>复制代码

父组件通过methods事件 通过事件 触发 this.$children[1].message="hello"来向子组件中传递值,1为父组件中第一个子组件,

子组件通过this.$parent.message=this.mymessage来修改  父组件中message 的值.

7. vuex处理组件之间的数据交互

如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值