在做项目时我们经常需要将组件进行封装,封装组件不可避免的就是组件间的传值,常见的组件传值的方法有以下几种:
1.父传子:通过自定义属性进行传值
父组件传值:
<children :num="a" ></children> //父组件中引用子组件,通过自定义属性传值
export default {
data: {
a: ' 12 '
}
}
子组件接收:
export default {
props: {
num: Number //num接收到父组件的传值,可以在方法或通过el表达式使用
},
}
2.子传父:通过自定义方法实现
子组件传值:
<el-button @click="send"></el-button> //通过子组件的ui控件绑定的事件中传值,
//也可以是其他ui控件,这里以button按钮为例
send(){
this.$emit("recieve",e); //recieve表示事件名,e是需要传递的参数
}
父组件接收:
<children @recieve="get"></children> //自定义事件通过get方法实现
get(e){
console.log(e) //get方法的参数e就是子组件传递过来的
}
3.兄弟组件的传值
兄弟组件的传值与子传父的方法类似,只不过通过一个中间件eventBus.js进行传值,可以理解为二者的桥梁,使用时只需要引入自定义的eventBus.js,调用它的方法即可,子组件给父组件传值的时候调用的是自己的emit方法,这里实际上就是把eventBus作为一个公共的传值工具,调用他的emit方法进行传值,在需要接收的方法通过 this.$on() 进行接收,用到的较少。
定义bus.js 文件:
import Vue from 'vue';
// 使用 Event Bus
const bus = new Vue();
export default bus;
组件使用bus传值:
需要传值和接收的组件的script中引入该文件
import bus from '../common/bus';
传值一方在方法中调用emit方法传值
bus.$emit('collapse', this.collapse);
接收一方在方法中调用on方法接收
bus.$on('collapse', msg => {
this.collapse = msg;
});
组件使用bus接收:
4.通过调用组件的reload()方法传值
这种传值方法在开发还是经常使用的,在父组件中调用子组件的reload方法,同时传递参数给子组件,根据新的参数reload重新加载UI控件,比如table表等等。
父组件中调用:(以学生表和教师表为例)
<children ref="children"></children>
getType(e){ //getType方法获取需要显示的表格类型
this.type = e; //e='xs',假设传递的值为xs,需要展示学生表
that.$refs?.children?.reload(that.type);
}
子组件通过reload方法接收:
<el-table v-if="type == 'xs' "> ...</el-table>
<el-table v-if="type == 'js' "> ...</el-table>
methods:{
reload(e){
this.type = e; //此时type值为接收到的xs展示学生表,reload重新加载表格
}
}
5.神器pubsub,不受组件的关系影响。
Redis 支持消息的发布订阅模式,订阅者(Sub)通过SUBSCRIBE 命令和PSUBSCRIBE命令向redis 服务订阅频道(channel),当发布者通过PUBLISH 命令向chinnel发布命令时,订阅该频道的客户端都会受到此消息。
借鉴这个思想,vue也可以通过pubsub进行组件间的传值,只需要存在发布订阅关系就可以进行传值,不再受是什么组件的影响,首先需要在项目中安装配置pubsub插件(网上很多安装教程)
使用方法:
A. 在需要的组件的 script 标签中引入pubsub
import PubSub from 'pubsub-js'; //发布订阅的组件都需要导入
B. 在需要传值的方法使用pubsub的publish方法:
change(e){ //比如在这个组件中我们需要动态改变id并将id的变化并传递给另一个组件
this.id = e;
PubSub.publish('id', this.id);
}
C. 在接收的组件通过subscribe方法接收:
mounted(){ //在mounted中接收
PubSub.unsubscribe('id'); //取消订阅
PubSub.subscribe('id', this.getId); //类似于自定义事件接收,调用getId()方法订阅接收id的值
}
method(){
getId(_, res){ //接收数据的方法,它的参数第一个为接收的订阅名,不需要调用,可直接用_来占位,避免eslint报错。第二个为传来的数据,当传有多个数据时,可用一个对象来传递。
this.id = res;
this.initData(); //比如可以根据新的id做一些操作,比如调用接口方法更新数据,因为pubsub是实时接收的,所以只要id一变订阅者就能接收到,就会调用getId方法,同时getId方法调用的接口方法会被调用,起到实时根据id更新数据的效果。
}
}
pubsub的使用非常方便,比如我们需要通过多个组件中转传值的时候,比如a -> c需要通过a -> b -> c,需要通过的组件越多越容易传错是非常头疼的问题,如果有这种直接在组件传递方和接收方搭建桥梁的方法何乐而不为呢?