这是我参与「第四届青训营 」笔记创作活动的第12天。今天介绍的是vue中组件的通信方式总结。
通信方式
vue组件的通信方式
- props/$emit
- v-solt :可以传递DOM
$refs
/$parent
/$children
/$root
:直接拿到整个组件实例对象,在父组件中操作子组件的实例对象,这样逻辑混乱,不建议使用。$attrs
/$listener
- provide/inject
- eventBus
- vuex
- 父子通信:1,2,3,4,5,6,7
- 兄弟通信:6,7
- 跨级通信:4,5,6,7
具体使用方法
1.props --父传子
让子组件中的 props配置项 接收父组件利用 自定义属性 传过来的数据
三种写法:
- 只接收 prop:['name','age']
- 限制接收类型 props:{name:String,age:Number}
- 限制类型、必要性、默认值
props:{
name:{
type:String,
required:true,
default:'zhang'
}
}
注意: props是只读的,Vue底层会监测是否对props进行修改,如果进行了修改,会发出警告。实在需要修改,将props的内容复制到data中,对data的数据修改。
2.$emit 自定义事件 --子传父
绑定步骤
- 父组件给子组件绑定自定义事件
<Futher @事件名="方法">
或<Futher v-on:事件名="方法">
- 自定义事件的回调函数定义在父组件中
- 在子组件中触发自定义事件,并传入参数
触发自定义事件
this.$emit('事件名',数据)
- 解绑自定义事件
this.off('事件名')
绑定原生DOM事件 native
组件上可以绑定原生DOM事件,将原生DOM事件识别为自定义事件,需要手动触发才能执行
使用修饰符native实现
@click.native="show"
3.v-model --子传父
是一套语法糖,在子组件使用时,使用v-model属性,是以下两个操作的简写形式
- 自动绑定value属性
- 自动传递@input事件
<Child v-modle="keyname">
<Child v-bind:value="keyname" @input="(value)=>{keyname=value}">
在子组件内部:
使用 props:[value] 接收value数据
调用this.$emit("input",value) 修改父组件中的keyname
4.ref --父传子
用来获取DOM元素或组件实例对象 ---不建议使用
使用方式:
- 打标识:
<h1 ref="xxx"></h1>
或<Child ref="xxx"></Child>
- 获取:
this.$refs.xxx
注意!
- 虽然可以通过ref拿到DOM节点,但是不建议在vue中直接操作DOM节点
- 通过ref拿到组件实例对象后,可以获取子组件的data,但是不建议直接使用ref方法---在子组件不知道的情况操作其data
5.中间人模式 --非父子通信
该模式比较麻烦,只适用于亲兄弟之间通信,
Child1传给Father,Father再传给Child2
6.全局事件总线 bus通信 --非父子通信
适用于任意组件间的通信
定义全局事件总线,要使得所有的组件对象都能看见,所以放在Vue的原型对象中。
new Vue({
beforeCreate(){
Vue.prototype.$bus = this
}
})
订阅发布模式
- 订阅者
- 订阅时机 生命周期mounted(挂载完毕)中订阅
this.$bus.$on("事件名","回调函数")
- 发布者
调用事件,传递参数
this.$bus.$emit("事件名","传递的参数")
7.依赖、注入 provide/inject --父(祖先)传子
这种方式就是Vue中的依赖注入,该方法用于父子组件之间的通信。当然这里所说的父子不一定是真正的父子,也可以是祖孙组件,在层数很深的情况下,可以使用这种方法来进行传值。就不用一层一层的传递了。
provide / inject
是Vue提供的两个钩子,和data
、methods
是同级的。并且provide
的书写形式和data
一样。
provide
钩子用来发送数据或方法inject
钩子用来接收数据或方法 注意: 依赖注入所提供的属性是非响应式的。
8.VUEX --任意组件通信
作为一个容器,用于管理会被多个组件访问和修改的数据