避免篇幅过长,暂时不做举例
1、props
实现父子之间的通信
- 父向子传值
//在父组件中调用子组件并通过v-bind传递prop,子组件用props接收
- 子向父传值
//子组件通过$emit的方式将事件传递给父组件,父组件通过v-on接收
this.$emit(事件名,数据)
2、$emit
和$on
这种方式通过一个空的vue实例作为中央事件总线(事件中心),用它来触发和接收事件
这种方式可以实现任何组件之间的通信,包括父子、跨级、兄弟
具体实现方式
var Bus=new Vue();
//创建一个空的vue实例作为事件中心
Bus.$emit(事件名,数据);
//发布数据
Bus.$on(事件名,data => {});
//订阅数据
3、provide
和inject
Vue2.2.0新增API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。
provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
//父组件
export default {
provide: {
name: '父组件的name'
}
}
//子组件
export default {
inject: ['name'],
mounted () {
console.log(this.name); // '父组件的name'
}
}
provide 和 inject 绑定并不是可响应的
。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的
provide和inject实现数据响应式
- provide
祖先组件的实例
,然后在子孙组件中注入依赖,这样就可以在子孙组件中直接修改祖先组件的实例的属性,不过这种方法有个缺点就是这个实例上挂载很多没有必要的东西比如props,methods - 使用2.6最新API
Vue.observable
优化响应式 provide (推荐)
4、vuex
这个就不展开说了
5、$attrs
和 $listeners
$attrs
包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过
v-bind="$attrs"
传入内部组件——在创建高级别的组件时非常有用。
通俗的讲,祖先组件使用v-bind向子孙组件传递参数,且子孙组件一直没有使用props来接收的时候,$attrs
会接收到祖先组件传递的所有值,如果有值被props接收了,$attrs
中就会失去这个值
下面这篇文章中的例子很直观
Vue2.4中$attrs
和$listeners
的使用-学习笔记
6、$children
$parent
和ref
这几种方法都是获取组件实例,弊端是无法在跨级和兄弟之间通信
vue官方文档中描述$children不保证子组件的顺序
当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。
// 父组件使用子组件时 给子组件添加一个ref属性
<Child ref='child'/>
// 在父组件中就可以直接取到子组件的实例
const child = this.$refs.child
// 可以直接访问子组件的数据
console.log(child.title)
7、sync语法糖
子组件通知父组件数据更新的时候可以使用
正常子组件向父组件传递值得时候可能要用到$emit 和v-on
有了sync语法糖之后,我们就可以简化这个流程
methods:{
handleChange(){
this.$emit('update:user','newUser')
}
}
父组件接收时直接.sync就可以接收
<Child :user.sync='user'/>