vue组件通讯

最近一直在写报表的页面,也碰到了非常多组件通讯的问题,最近准备重构和总结一下。因为之前是第一次上手vue-cli + echarts + mint-ui,所以前一次写的代码自己非常的不满意。第一次的报表完成图,大致如下gif所示。下面就是总结一下一些组件通讯的方式吧。温故知新。

报表页面

父子组件通讯

数据从父组件到子组件

数据从父组件到子组件是最容易理解的,因为vue是单向数据流,所以数据就像水流一样,从高处到低处,这里为理解为,从父组件流向子组件。 vue

目录如下所示 vue Main.vue

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
<template>
<div class="main">
//需要传递到子组件的数据,并且绑定到type上
<header-nav :type="type"></header-nav>
</div>
</template>

<script>
import HeaderNav from './HeaderNav.vue';
export default {
name: 'hello',
components: {
HeaderNav
},
data() {
return {
type: {
summary: '汇总',
trend: '走势',
},
selected: 1
}
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style lang="stylus" rel="stylesheet/stylus">

</style>

HeaderNav

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
<template>
<div class="header">
<mt-navbar v-model="selected">
<mt-tab-item id="summary">{{type.summary}}</mt-tab-item>
<mt-tab-item id="trend">{{type.trend}}</mt-tab-item>
</mt-navbar>

<!-- tab-container -->
<mt-tab-container v-model="selected">
<mt-tab-container-item id="1">
summary
</mt-tab-container-item>
<mt-tab-container-item id="2">
trend
</mt-tab-container-item>
</mt-tab-container>
</div>
</template>

<script>
export default {
name: 'headerNav',
//父组件传递来的数据
props: ['type'],
data() {
return {
selected:"summary"
}
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="stylus" rel="stylesheet/stylus">
.test
font-size 50px
</style>

数据从子组件到父组

子组件将数据传递到父组件,主要到方法是$emit()和$on方法 vue自定义事件

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

Main.vue

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
<template>
<div class="main">
<!--通过on-v绑定transferUser自定义事件监听 transferUser为子组件中的自定义事件-->
<header-nav :type="type" @transferUser="getUser"></header-nav>
<span>this is name</span>
<span>{{user}}</span>
<br>
<router-link to='/selectTime'>
selectTime
</router-link>
</div>
</template>

<script>
import HeaderNav from './HeaderNav.vue';
import selectTime from './selectTime.vue';
export default {
name: 'hello',
components: {
HeaderNav,
selectTime
},
data() {
return {
type: {
summary: '汇总',
trend: '走势',
},
selected: 1,
user: '',
}
},
methods: {
getUser(msg){
this.user = msg
}
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style lang="stylus" rel="stylesheet/stylus">

</style>

HeaderNav.vue

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
<template>
<div class="header">
<!--出发change事件调用setUser,绑定自定义事件transferUser,并传入参数-->
<input type="text" v-model="username" @change="setUser">
</div>
</template>

<script>
export default {
name: 'headerNav',
props: ['type'],
data() {
return {
selected:"summary",
username:''
}
},
methods: {
// 触发自定义事件
setUser:function(){
this.$emit('transferUser', this.username)
}
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="stylus" rel="stylesheet/stylus">
.test
font-size 50px
</style>