组件间的关系有父子关系、兄弟关系、祖孙关系和远亲关系。
不同的关系间,组件的通信有不同的方式。
$emit
prop
向下传递,emit
向上传递。
父组件使用 prop
向子组件传递信息。
ParentComponent.vue
ChildComponent.vue
{{ msg }}
子组件通过实例的事件方法 $emit
向父组件通信
$emit
触发一个自定义事件,并接受一个参数作为抛出值。父组件通过 $event
或回调函数获取传递值。
ParentComponent.vue
{{ msg }}
ChildComponent.vue
优先使用 prop
和 事件进行父子组件间的通信。
$parent
和 $children
子实例可以用 this.$parent
访问父实例,同时子实例被推入父实例的 $children
数组中。
ParentComponent.vue
父组件
来自子组件 1 的消息:{{ msg1 }}
来自子组件 2 的消息:{{ msg2 }}
ChildComponent1.vue
子组件1
ChildComponent2.vue
子组件2
依赖注入设置两个选项:provide
和 inject
provide
选项允许我们提供一系列数据或方法。然后在设置了 provide
选项的组件的所有后代组件里都可以通过 inject
选项获取这些数据或方法。
provide
选项应该是一个对象或返回一个对象的函数。
provide: {
foo: 'bar'
}
provide: {
return {
foo: 'bar'
}
}
inject
选项可以为以下值:
provide
属性的 key。provide
不同,如果要设置为不同名的属性,那么就要给该属性设置 from
属性来说明它来自哪个 provide
提供的属性,同时你可以为它提供默认值 default
。inject: ['foo']
inject: {
foo: {
from: 'bar'
default: 'foo'
}
}
ref
和 $refs
ref
属性为普通 DOM 元素或子组件指定引用,该引用会被注册到父组件的 $refs
对象上。
<div ref="div">div>
<child-component ref="child" />
使用
vm.$refs.div
vm.$refs.child
如果你尝试在 created
或 mounted
钩子中访问 ref
,通常会得到 undefined
。因为 ref 本身是作为渲染结果被创建的,在初始渲染(beforeUpdate
之前)的时候你不能访问它们。
使用事件总线进行组件间通信的步骤:
1.创建事件总线
// EventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
2.引入事件总线
import { EventBus } from './EventBus.js';
3.在发送组件中触发事件
EventBus.$emit('custom-event',eventData);
4.在接收组件中监听事件
EventBus.$on('custom-event',(data)=>{
//处理 data
});
5.移除监听事件
EventBus.$off('custom-event')
$attrs
与 $listeners
$attrs
包含了父组件传递给子组件的所有没有在子组件 props 中声明的属性(除了class
和style
)。当子组件没有声明任何props时,$attrs
中会包含所有父组件传递的属性(除了class
和style
),这在创建高级别的通用组件时非常有用,因为你无需知道父组件会传递哪些属性。
下面是一个示例来说明$attrs
的用法:
假设我们有一个名为MyButton
的子组件,它可以接收label
属性,但同时也希望允许父组件传递任意额外的HTML属性给按钮元素。我们可以使用$attrs
来实现这一点:
在这个示例中,MyButton
组件只声明了一个名为label
的prop,但它使用v-bind="$attrs"
将所有父组件传递的属性绑定到按钮元素上。这意味着,父组件可以像这样使用MyButton
:
<MyButton label="Click me" class="btn btn-primary" id="my-button" @click.native="handleClick" />
在这里,class
和id
属性会被传递到元素,而
label
会被解析为"Click me"
,同时@click
事件也会正常工作。
$listeners
包含了父作用域中的 (不含 .native
修饰器的) v-on
事件监听器。它可以通过 v-on="$listeners"
传入内部组件——在创建更高层次的组件时非常有用。
ParentComponent.vue
MyButton.vue
以后专门学习,在此不做介绍先。
MDN-客户端存储