VUE父子组件通信
在Vue2.x版本以后,父子组件之间的通信变得比较容易,层次结构也比较清晰。主要通信方案主要有props+ $emit 方式、创建一个公用的VUE空实例类对象保存公用的数据、使用vuex进行公用的状态管理。接下来我们将对这几种方式一一介绍。
props + $emit()
此方式适用于父组件与自组件进行数据通信。那这种方式的数据传递方式是什么呢?简单来说,就是在父组件中,通过props属性的方式将数据传递给子组件,子组件在进行相关数据操作后,通过$emit() 再将值传递给父组件,通知父组件修改相关值。我们来看一下实例:
父组件:
// 父组件中,通过props的方式将值传递给子组件
<parent-component> // 为了保证代码风格的优良,在写组件是最好将驼峰写成html标签形式
// 在这里,我们将使用myProp这个属性去接受来自父组件的数据value
<child-component :my-prop="value"></child-component>
</parent-component>
在子组件中创建props,创建方式有三种,一般视情况而定,此处使用最全的一种写法作为实例,其余两种由同学自行扩展:
export default {
name: "childComponent",
props: {
myProp: { // 用于接收父组件所传递的值
type: [Object, Array], // 可以为属性指定数据类型
default: null, // 为属性指定默认值, 父组件传递的值会覆盖该值
required: true, // 是否为必须的属性
validator: function(value){ // 属性验证规则,当不满足条件时,属性值将不会正确获取,并且会在开发控制台报错
// 验证规则
}
}
}
}
子组件中,props的validator会在组件创建实例之前验证,所以其中是不能使用组件的属性。
通过这种方式,子组件就可以获取到父组件传入的值。但这种方式目前为止,只属于单向传递,如果在子组件直接修改prop值的话,Vue将会报错,这时就需要使用$emit()将值传递给父组件;
子组件:
// 在子组件中,处理完数据之后,再将prop 通过$emit()传递给父组件
export default {
data() {
childValue: 0 // 创建一个数据值用于复制prop的值,因为prop为单向传递,不能直接修改
},
mounted(){
this.childValue = this.myProp;
this.childValue += 100; // 处理数据
this.$emit('changMyProp', this.childValue);// 通过$emit传递数据给父组件
}
}
父组件:
// 父组件中需要监听来自子组件的$emit
<parent-component>
// 事件监听来自子组件的$emit
<child-component :my-prop="value" @changeMyProp="onChangeValue"></child-component>
</parent-component>
export default {
method: {
// 监听事件
onChangeValue(value) {
this.value = value; // 将子组件传递过来的值赋值给父组件中的value
}
}
}
注意:在此处事件名称要与子组件中注册的$emit 事件名相同,并且函数具有默认参数
到此,父组件与子组件的第一种通信方式介绍完毕。
创建一个公用的VUE空实例类对象
这种方法,使用与非父子组件之间的通信,就是创建一个公用的vue空实例对象,用于保存各组件公用的数据。
首先,创建一个eventBus.js文件,用于创建一个空VUE实例对象:
// eventBus.js
import Vue from 'vue';
const EventBus = new Vue();
export default EventBus;
创建好vue空对象实例之后,我们分别在需要进行通信的两个组件中引入eventBus
import EventBus from '@/js/eventBus.js';
假设需要通信的组件是A组件和B组件,当需要将A组件中的数据传递到 B组件时,就可以在A组件中通过EventBus使用$emit触发一个事件,并传入相关值:
changeValue() {
this.testValue = 100;
EventBus.$emit('numberChange', this.testValue);
}
然后,在B组件中,用EventBus通过$on在组件挂载时,接受到A组件传过来的值:
mounted(){
EventBus.$on('numberChange', (value) => {
console.log(value)
});
}
如此,我们便能实现非父子组件之间的通信了。
VUEX
vuex是一个优秀的vue状态管理库,由于篇幅较多,再次不在对其进行阐述,我将专门开设一篇文章详细介绍Vuex。