一.组件通信常用方式
- props
- $emit/on
- event bus
// 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', (data) => console.log(data)) // console 123
// child2
this.$bus.$emit('foo','123')
- vuex
- $parent/root
// $parent/$root
//兄弟组件之间通信可通过共同祖辈搭桥,$parent或$root。
// brother1
this.$parent.$on('foo', (data) => console.log(data)) // console 123
// brother2
this.$parent.$emit('foo','123')
- $children
// $children
// 父组件可以通过$children访问子组件实现父子通信。
// parent
this.$children[0].xx = 'xxx'
//注意:$children不能保证子元素顺序(如果存在异步组件,位置就不一定对,或者有v-if,,动态组件等)
- $refs
// $refs
// 获取子节点引用
// parent
<HelloWorld ref="hw"/>
mounted() {
this.$refs.hw.xx = 'xxx'
}
//注意:$ref与$children的区别,,ref可以是元素,children只能是子组件
- provide/inject
// provide/inject
// 能够实现祖先和后代之间传值,不是响应式的
// ancestor
provide() {
return {foo: 'foo'}
}
// descendant
inject: ['foo']
provide实现响应可以通过一下2种方法
//1.provide提供祖先组件的实例
provide(){
return {
theme: this
}
}
//2.使用2.6最新API,vue.observable优化响应式provide
provide() {
this.theme = vue.observable({
color: 'blue'
})
}
- 非props属性($attrs/listener)
// $attrs/$listeners
// 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 ( class 和 style 除外)。当一个组件没有 声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外),并且可以通过 v-bind="$attrs" v-on="$listeners" 传入内部组件——在创建高级别的组件时非常有用。
// child:并未在props中声明foo
<p>{{$attrs.foo}}</p>
// parent
<HelloWorld foo="foo"/>
二.vue组件插槽
- 匿名插槽(将内容全部插入子组件slot里面)
// comp1
<div>
<slot></slot>
</div>
// parent
<comp>hello</comp>
- 具名插槽(将内容分发到子组件指定位置)
// comp2
<div>
<slot></slot>
<slot name="content"></slot>
</div>
// parent
<Comp2>
<!-- 默认插槽用default做参数 -->
<template v-slot:default>具名插槽</template>
<!-- 具名插槽用插槽名做参数 -->
<template v-slot:content>内容...</template>
</Comp2>
- 作用域插槽(分发内容要用到子组件中的数据)
// comp3
<div>
<slot :foo="foo"></slot>
</div>
// parent
<Comp3>
<!-- 把v-slot的值指定为作用域上下文对象 -->
<template v-slot:default="slotProps"> 来自子组件数据:{{slotProps.foo}}</template>
</Comp3>