vue兄弟组件间的传值

方法一

  1. 先由A子组件通过 $emit 传值给父组件

  2. 再由父组件通过事件接收传给B子组件

  3. 最后由B组件通过 props 接收传值

使用场景:管理后台的头部(Header)和左边导航栏(Aside)分别为子组件,并且同时被Home组件引用,我们头部组件上面要显示 面包屑 功能,选中哪个导航栏 面包屑 就显示对应的导航栏名称。
注意:这里我用了 element-ui 框架

Aside组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<template>
<div>
<el-menu default-active="2" class="el-menu-vertical-demo" @select="selectMenu">
<router-link to="/menu1">
<el-menu-item index="1">
<i class="el-icon-menu"></i>
<span slot="title">导航一</span>
</el-menu-item>
</router-link>
<router-link to="/menu2">
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
</router-link>
<router-link to="/menu3">
<el-menu-item index="3">
<i class="el-icon-setting"></i>
<span slot="title">导航三</span>
</el-menu-item>
</router-link>
<router-link to="/menu4">
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</router-link>
<router-link to="/menu5">
<el-menu-item index="5">
<i class="el-icon-setting"></i>
<span slot="title">导航五</span>
</el-menu-item>
</router-link>
</el-menu>
</div>
</template>

<script>
export default {
name: "",
methods:{
selectMenu(index){
this.$emit('passIndex',index);
}
}
}
</script>

Home组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<template>
<div class="homeBox">
<el-container>
<el-header style="background:#eee;lineHeight:60px;">
<Header :tabIndex="tabIndex"></Header>
</el-header>
<el-container>
<el-aside width="200px">
<Aside @passIndex="getIndex"></Aside>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>

<script>
import Aside from '../components/Aside'
import Header from '../components/Header'

export default {
name: "home",
data(){
return{
tabIndex: '1'
}
},
components: {
Aside,
Header
},
methods:{
getIndex(index){
this.tabIndex = index;
}
}
};
</script>

Header组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<template>
<div>
<div class="left">面包屑 / {{title}}</div>
头部
</div>
</template>

<script>
export default {
name: "",
props: {
tabIndex: String
},
watch:{
tabIndex(){
if(this.tabIndex){
switch (this.tabIndex) {
case '1':
this.title = '导航一';
break;
case '2':
this.title = '导航二';
break;
case '3':
this.title = '导航三';
break;
case '4':
this.title = '导航四';
break;
case '5':
this.title = '导航五';
}
}
}
},
data(){
return{
title:'导航二'
}
}
}
</script>

<style scoped>
.left{
float: left;
}
</style>

方法二

  1. 兄弟之间传递数据需要借助于事件车,通过事件车的方式传递数据

  2. 创建一个Vue的实例,让各个兄弟共用同一个事件机制。

  3. 传递数据方,通过一个事件触发bus.$emit(方法名,传递的数据)。

  4. 接收数据方,通过mounted(){}触发bus.$on(方法名,function(接收数据的参数){用该组件的数据接收传递过来的数据}),此时函数中的this已经发生了改变,可以使用箭头函数。

我们可以创建一个单独的js文件eventBus.js,内容如下

1
2
3
import Vue from 'vue'

export default new Vue

Aside组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<template>
<div>
<el-menu default-active="2" class="el-menu-vertical-demo" @select="selectMenu">
<router-link to="/menu1">
<el-menu-item index="1">
<i class="el-icon-menu"></i>
<span slot="title">导航一</span>
</el-menu-item>
</router-link>
<router-link to="/menu2">
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
</router-link>
<router-link to="/menu3">
<el-menu-item index="3">
<i class="el-icon-setting"></i>
<span slot="title">导航三</span>
</el-menu-item>
</router-link>
<router-link to="/menu4">
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</router-link>
<router-link to="/menu5">
<el-menu-item index="5">
<i class="el-icon-setting"></i>
<span slot="title">导航五</span>
</el-menu-item>
</router-link>
</el-menu>
</div>
</template>

<script>
import eventBus from '../assets/js/eventBus'
export default {
name: "",
methods:{
selectMenu(index){
eventBus.$emit('passIndex',index);
}
}
}
</script>

Header组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<template>
<div>
<div class="left">面包屑 / {{title}}</div>
头部
</div>
</template>

<script>
import eventBus from '../assets/js/eventBus'
export default {
name: "",
data(){
return{
title:'导航二'
}
},
mounted(){
eventBus.$on("passIndex", (index) => {
switch (index) {
case '1':
this.title = '导航一';
break;
case '2':
this.title = '导航二';
break;
case '3':
this.title = '导航三';
break;
case '4':
this.title = '导航四';
break;
case '5':
this.title = '导航五';
}
})
}
}
</script>

<style scoped>
.left{
float: left;
}
</style>

方法三

通过 vuex 状态管理来实现兄弟组件间传值,直接上代码

Header组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<template>
<div>
<div class="left">面包屑 / {{activeName}}</div>
头部
</div>
</template>

<script>
export default {
name: "",
data(){
return{

}
},
computed:{
activeName(){
switch (this.$store.state.activeName) {
case '1':
return 'introJs使用';
case '2':
return 'Vuex学习';
case '3':
return 'sync修饰符';
case '4':
return '组件传值';
case '5':
return '导航五';
}
}
},
mounted(){

}
}
</script>

<style scoped>
.left{
float: left;
}
</style>

Aside组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<template>
<div>
<el-menu default-active="2" class="el-menu-vertical-demo" @select="selectMenu">
<router-link to="/menu1">
<el-menu-item index="1">
<i class="el-icon-menu"></i>
<span slot="title">introJs使用</span>
</el-menu-item>
</router-link>
<router-link to="/menu2">
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">Vuex学习</span>
</el-menu-item>
</router-link>
<router-link to="/menu3">
<el-menu-item index="3">
<i class="el-icon-setting"></i>
<span slot="title">sync修饰符</span>
</el-menu-item>
</router-link>
<router-link to="/menu4">
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">组件传值</span>
</el-menu-item>
</router-link>
<router-link to="/menu5">
<el-menu-item index="5">
<i class="el-icon-setting"></i>
<span slot="title">导航五</span>
</el-menu-item>
</router-link>
</el-menu>
</div>
</template>

<script>
export default {
name: "",
methods:{
selectMenu(index){
this.$store.commit('setActiveName',index);
}
}
}
</script>

store.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
state: {
count: 1,
activeName:'2' //默认值
},
mutations: {
//传值
add(state,num) {
state.count+=num
},
reduce(state){
state.count--
},
setActiveName(state,name){ //修改方法
state.activeName = name;
}
},
});

export default store;

以上代码你可以直接复制粘贴自己跑一下试试!

或者直接clone我的代码 https://github.com/hutaoao/vue_study
代码里面包含父子组件传值、路由嵌套重定向等。

海盗船长 wechat
扫码关注我的公众号哟
0%