vue组件通信方式

159 阅读1分钟

组件通信常用方式

 1.props
 2.$emit/$on
 3.event bus(事件总线)
 4.vuex

自定义事件

边界情况

(事件的派发者和监听者通常都是同一个)
1.$parent
2.$children(和refs不一样的是这个只能是自定义组件,不包括原生的;
refs即可以获取自定义组件也可以原生元素)
3.$root
4.$refs
5.provide/inject

非prop特性

 1.$attrs
 2.$listeners

props

父给子传值

//child
props: { msg: String }
// parent
<HelloWorld msg="Welcome to Your Vue.js App"/>

子给父传值

// child 
this.$emit('add', good)
// parent
<Cart @add="cartAdd($event)"></Cart>

事件总线

任意两个组件之间传值常用事件总线 或 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已经实现了相应接口

parent/parent/root

兄弟组件之间通信可通过共同祖辈搭桥,parentparent或root。

// brother1
this.$parent.$on('foo', handle) 
// brother2 
this.$parent.$emit('foo')

$children

父组件可以通过$children访问子组件实现父子通信。

 //parent 
 this.$children[0].xx = 'xxx'

$children不能保证子元素顺序

attrs/attrs/listeners

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

// child:并未在props中声明foo 
<p>{{$attrs.foo}}</p>
// parent
<HelloWorld foo="foo"/>

refs

获取子节点引用

// parent
<HelloWorld ref="hw"/>
mounted() { 
 this.$refs.hw.xx = 'xxx'
}

provide/inject

// ancestor
provide() {
return {foo: 'foo'}
}
// descendant
inject: ['foo']
此处可以用对象形式避免重名
inject:{
  foo1:'foo'
}
还可以设置默认值
inject:{
  foo1:{
   from:'foo',
   default:'123'
  }
}
为了响应式的可以传递引用类型对象

vuex专门章节