组件通信分类:
- 父子组件通信
- 兄弟组件通信
- 祖孙与后代组件通信‘
- 非关系组件通信
常见的8种通信方式
1. 通过props传递
使用场景:父传子
使用方式:子组件设置声明props属性,定义接收父组件传递过来的参数;父组件在使用子组件标签中通过字面量来传递值
//子组件Child.vue
//定义接收参数
props:{
name:String; //字符串类型
age:{ //对象类型
type:Number,
default:18, //默认值
require:true //表示父组件必须传递age参数
}
}
//父组件使用子组件
<Child name="张三" age=20/>
标题2. $emit触发自定义事件
使用场景:子传父
使用方式:子组件通过$emit触发自定义事件,传值;父组件绑定监听器获取子组件传递过来的值
//子组件Child.vue
<input @click="onClick"/> //设置自定义事件
...
methods:{
onClick(){
this.$emit('toValue',"传递的值")
}
}
//父组件
<Child @toValue="getValue"/> //传递一个值时可以不带参数,传递多个值的时候必须带参数
...
data(){
return{
value:'',
}
}
methods:{
getValue(value){
this.value = value; //传递多个值的时候,此时的value是一个数组
}
}
3. ref
使用场景:父拿子值
使用方式:父组件在使用子组件的时候设置ref;父组件通过设置子组件ref来获取数据;然后可以在父组件中通过ref去改变子组件的属性值
//子组件Child.vue
data(){
return:{
value:"我是子组件中的值"
}
},
methods:{
setValue(){
console.log("我是子组件中的方法");
}
}
//父组件
<Child ref="foo"/>
<button @click="getValue"/>
...
methods:{
getValue(){
console.log(this.$refs.foo.value); //输出 我是子组件中的值
console.log(this.$refs.foo.setValue()); //输出 我是子组件中的方法
}
}
4. evenBus
使用场景:兄弟组件传值
使用方式:单独创建一个中央事件总线eventBus,new一个vue的一个新的实例,类似于一个站,连着两个组件;兄弟组件通过$emit出发自定义事件,传递参数;另一个组件通过$on监听自定义事件
//eventBus.js
//创建一个bus实例
import Vue from 'Vue'
export default new Vue
// 兄弟组件1 brother.vue
<input @click="onClick"/> //设置自定义事件
...
// 引入bus
import bus from '../assets/eventBus'
export default{
methods:{
onClick(){
this.$emit('toValue',"传递的值")
}
}
}
//兄弟组件2
<p>从兄弟组件1接收到的信息:{{msg}}</p>
...
//引入bus
import bus from '../assets/eventBus'
data(){
return{
msg:'默认值',
}
},
mounted(){
var that = this;
//通过$on监听自定义事件
bus.$on("toValue",function(msg){
that.msg = msg;
})
}
5.$parent、$children
使用场景:父传子、子传父
使用方式:分别在子组件、父组件中直接分别使用$parent 、$children,获取对方的数据即可
举例$children,两者使用方式一样
//子组件Child.vue
//定义接收参数
data(){
return{
name:"张三";
}
},
methods:{
setValue(){
console.log("我是子组件中的方法");
}
}
//父组件使用子组件
<Child />
...
mounted () {
// 获取到所有的子组件,结果是一个数组
console.log(this.$children)
// 获取指定子组件中的指定数据
console.log(this.$children[0].value)
// 调用子组件的方法
this.$children[0].setValue()
}
6.$attrs与$listeners
使用场景:组先传递数据给后代
使用方式:设置批量向下传属性$attrs和$listeners;
$attrs包含了父级作用域中不作为props被识别的特性绑定:v-bind="$attrs" 将所有的非props属性绑定到相应标签;
所有组件上的方法绑定子组件都可以通过$listeners接收: v-on="$listeners" 将所有的方法又绑定到组件相应标签
7.project与inject
使用场景:祖先传递数据给后代
使用方式:组先组件中定义project属性,返回传递的值;后代组件中通过inject接收传递过来的值
//祖先组件,在祖先组件中定义provide属性,返回传递的值
provide(){
return{
value:'我是祖先组件中的值',
}
}
//后代组件,在后代组件中通过inject接收组件传递过来的值
inject:['value']
8.vuex
使用场景:复杂关系的组件数据传递
Vuex作用相当于一个用来存储共享变量的容器
使用方式:
state:用来存放共享变量的地方
getter:用来获取共享变量的值
mutations:用来存放修改state的方法
actions:用来存放修改state的方法,不过action一般做一些异步操作。
总结
组件数据传递类型,可选择的方法:
- 父子关系:propos(父传子)、$emit(子传父),ref(父拿子值)
- 兄弟关系:$eventBus、 p a r e n t ( 通 过 共 同 祖 辈 parent(通过共同祖辈 parent(通过共同祖辈parent搭建通信桥连)
- 祖先后代:$attrs与$listeners 、project与inject
- 复杂关系:Vuex
如果这篇文章对你有帮助的话,就留下一个赞👍吧!