VUE组件之间通信的形式有哪些(SSS)

常见应用场景能够分为三类:

  • 父子通信:

    • null

父向子传递数据是通过 props ,子向父是通过 $emit / $on

* `$emit / $bus`  * `Vuex` * 通过父链 / 子链也能够通信( `$parent` / `$children` ) * `ref` 也能够拜访组件实例 
  • 兄弟通信:

    • $emit / $bus
    • Vuex
  • 跨级通信:

    • $emit / $bus
    • Vuex
    • provide / inject API
    • $attrs/$listeners

$emit / $bus

// main.js Vue.prototype.$bus = new Vue() // event Bus 用于无关系组件间的通信。 

A触发B

 //  A  this.$bus.$emit('new-messsage-at-me', {     data: { conversationID: message.conversationID }   })           
//  B   mounted() {     this.$bus.$on('new-messsage-at-me', event => {       if (         event.data.conversationID === this.conversation.conversationID &&         this.conversation.conversationID !==           this.currentConversation.conversationID       ) {         this.hasMessageAtMe = true       }     })   }, 

父子组件通信

  1. 父组件向子组件传值( props ):
//App.vue父组件 <template>   <div id="app">     <users v-bind:users="users"></users>//前者自定义名称便于子组件调用,后者要传递数据名   </div> </template> <script> import Users from "./components/Users" export default {   name: 'App',   data(){     return{       users:["Henry","Bucky","Emily"]     }   },   components:{     "users":Users   } } 
//users子组件  // 注:组件中的数据共有三种模式:data、props、computed <template>   <div class="hello">     <ul>       <li v-for="user in users">{{user}}</li>//遍历传递过去的值,而后出现到页面     </ul>   </div> </template> <script> export default {   name: 'HelloWorld',   props:{     users:{           //这个就是父组件中子标签自定义名字       type:Array,       required:true     }   } } </script> 
  1. 子组件向父组件传值(B 组件中 $emit, A 组件中 v-on ):
// 子组件 <template>   <header>     <h1 @click="changeTitle">{{title}}</h1>//绑定一个点击事件   </header> </template> <script> export default {   name: 'app-header',   data() {     return {       title:"Vue.js Demo"     }   },   methods:{     changeTitle() {       this.$emit("titleChanged","子向父组件传值");//自定义事件  传递值“子向父组件传值”     }   } } </script> 
// 父组件 <template>   <div id="app">     <app-header v-on:titleChanged="updateTitle" ></app-header>//与子组件titleChanged自定义事件保持一致    // updateTitle($event)承受传递过去的文字     <h2>{{title}}</h2>   </div> </template> <script> import Header from "./components/Header" export default {   name: 'App',   data(){     return{       title:"传递的是一个值"     }   },   methods:{     updateTitle(e){   //申明这个函数       this.title = e;     }   },   components:{    "app-header":Header,   } } </script> 

$ref 与 $parent $children

  • 应用 this.$parent查找以后组件的父组件。
  • 应用 this.$children查找以后组件的间接子组件,能够遍历全副子组件, 须要留神 $children 并不保障程序,也不是响应式的。
  • 应用 this.$root查找根组件,并能够配合$children遍历全副组件。
  • 应用 this.$refs查找命名子组件( <firstchild ref="one"></firstchild> )( this.$refs.one )

$attrs / $listeners

  • 两者的呈现使得组件之间跨组件的通信在不依赖 vuex 和事件总线的状况下变得简洁,业务清晰。
  • A->B->C 多级组件嵌套须要传递数据时,通常应用的办法是通过vuex。如果仅仅是传递数据,而不做两头解决,应用 vuex 解决,未免有点杀鸡用牛刀。Vue 2.4 版本提供了另一种办法,应用 v-bind=”$attrs”, 将父组件中不被认为 props个性绑定的属性传入子组件中,通常配合 interitAttrs 选项一起应用。
  • 简略来说:$attrs 与 $listeners 是两个「对象」,$attrs 里寄存的是父组件中绑定的非 Props 属性, 惟一毛病 没在props定义的属性 会显示在生成的html标签上, 解决办法:通过inheritAttrs:false,防止顶层容器继承属性; $listeners里寄存的是父组件中绑定的非原生事件。

A父组件

<template>  <div>    <child-dom     :foo="foo"     :coo="coo"      v-on:upRocket="reciveRocket"    >    </child-dom>  </div> </template> <script>  import childDom from "@/components/ChildDom.vue";  export default {    name:'demoNo',    data() {      return {        foo:"Hello, world",         coo:"Hello,rui"     }   },  components:{childDom},  methods:{    reciveRocket(){       console.log("reciveRocket success")    }  } } </script> 

B子组件

<template>    <div>      <p>foo:{{foo}}</p>      <p>attrs:{{$attrs}}</p>      <childDomChild v-bind="$attrs" v-on="$listeners"></childDomChild>    </div> </template> <script> import childDomChild from './childDomChild'; export default {    name:'child-dom'    props:["foo"],    inheritAttrs:false, } </script> 

C子组件的子组件

<template>     <div>        <p>coo:{{coo}}</p>        <button @click="startUpRocket">我要发射火箭</button>    </div> </template> <script>  export default {    name:'childDomChild',    props:['coo'],    methods:{      startUpRocket(){        this.$emit("upRocket");        console.log("startUpRocket")      }    }  } </script> 

provide / inject

  • 实用于 隔代组件通信 先人组件中通过 provider 来提供变量,而后在子孙组件中通过 inject 来注入变量。 provide / inject API 次要解决了跨级组件间的通信问题,不过它的应用场景,次要是子组件获取下级组件的状态,跨级组件间建设了一种被动提供与依赖注入的关系。
  • 如果是繁多的只是拿数据应用,在父组件定义,则在所有子组件都能为之所用
  • 官网不倡议在利用中间接应用该方法,理由很间接:他怕你"管不好"

1.个别状况应用都是在app.vue配置为:

provide () {   return {     isTest: this   } }, 

2.所有子组件都能够援用 拿到app.vue外面的所有数据

 inject: ['isTest'], 

欢送留言~~~