Vue组件通信__Vue.js
发布于 4 年前 作者 banyungong 1544 次浏览 来自 分享
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

父子组件通信

props 和 $emit

props和$emit这是我们日常开发中最常使用的组件通信方式。父组件通过绑定属性来向子组件传递数据,子组件通过 props 属性来获取对应的数据,子组件则是通过派发 $emit事件将数据传递到父组件中。

  //父组件parent.vue
  
  <child :msg="msg"
         @updateParentMsg="updateParentMsg" />
  

  data() {
    return {
      msg: 'parent msg',
    }
  },
  methods: {
    updateParentMsg(msg) {
      this.msg = msg
    }
  }
  //子组件child.vue
 
  //接收父组件传递的数据
  props: {
    msg: String
  },
  methods: {
    change() {
      //派发一个updateParentMsg事件
      this.$emit('updateParentMsg', 'child msg')
    }
  }

$children / $parent / ref

  • ⽗组件可以通过$children访问⼦组件,子组件可以通过 $parent来访问父组件,不过一般情况下不推荐通过这种方式来实现组件通信。
  • ref: 访问子组件实例或子元素,使用后可以直接访问子组件的数据或调用子组件的方法。

非父子组件通信

事件总线

任意两个组件之间传值常⽤事件总线 或 vuex的⽅式。

// Bus:事件派发、监听和回调管理
class Bus {
 constructor(){
 this.callbacks = {}
 }
 $on(name, fn){
 this.callbacks[name] = this.callbacks[name] || []
 this.callbacks[name].push(fn)
 }
 $emit(name, args){
 if(this.callbacks[name]){
 this.callbacks[name].forEach(cb => cb(args))
 }
 }
}
// main.js
Vue.prototype.$bus = new Bus()
// child1
this.$bus.$on('foo', handle)
// child2
this.$bus.$emit('foo')

实践中通常⽤Vue代替Bus,因为Vue已经实现了相应接⼝

//main.js
Vue.prototype.$bus = new Vue() 

Vuex

Vuex是一个专为Vue.js应用程序开发的状态管理模式,通过它集中式的管理数据并通知组件状态变更。推荐在项目复杂的情况下使用。

provide/inject

provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。用于祖先组件和后代组件之间的通信,无论组件的层次有多深

//祖先组件
provide() {
 return {foo: 'foo'}
}
//后代组件
inject: ['foo']

注意:provide 和 inject 并非响应式的。当我们传入对象时,其对象中的属性便是响应式的。

$attrs / $listeners

包含了⽗作⽤域中不作为 prop 被识别(且获取)的特性绑定(class和style除外)。当⼀个组件没有 声明任何 prop 时,这⾥会包含所有⽗作⽤域的绑定(class 和 style 除外),并且可以通过 v-bind=" $attrs"传⼊内部组件—在创建⾼级别的组件时⾮常有⽤。

//parent.vue
<child :msg="msg"
          foo="foo"
          @updateParentMsg="updateParentMsg" />

//child.vue 并未在props中声明foo
<GrandSon v-bind="$attrs"
          v-on="$listeners" />

//GrandSon.vue
 <p [@click](/user/click)="change">{{$attrs.foo}}</p>
 
  methods: {
   change() {
     this.$emit('updateParentMsg', 'GrandSon msg')
   }
 }
```<p style="line-height: 20px; color: #ccc">
       版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
       作者: Yangi
       原文链接:<a href='https://juejin.im/post/6856359634039963656'>https://juejin.im/post/6856359634039963656</a>
     </p>
回到顶部