如果文中有出现纰漏、错误之处,还请大神您多指教。 本文将通过实例的方式记录一下 Vue 中组件之间的通信方式。 在 Vue中,需要组件通信的情况一般有以下几种:
父组件向子组件通信 子组件向父组件通信 兄弟组件通信
Vue 支持的通信方式
prop
$emit
类似 React 的 props 回调。
provide / inject
如果你熟悉 React,这与 React 的 context 特性很相似。
1、父组件向子组件通信(props)
Vue 和React数据流动是单向的,父组件通过 props 向子组件传递需要的信息。 新建一个名为 Com1 的 vue 文件。加入以下代码。
<template>
<div>
<div>com1</div>
<div>{{text}}</div>
</div>
</template>
<script>
export default {
name: 'Com1',
props: {
text: {
type: String,
default: ''
}
}
}
</script>
新建一个 vue 文件,或直接在 App.vue 上写,加入以下代码。
<template>
<div>
<Com1 text="我是 com1 的 props" />
</div>
</template>
<script>
import Com1 from './Com1'
export default {
name: 'app',
components: {
Com1,
}
}
</script>
完成后,运行效果如下图所示,我们在父组件传了个一句话到组件里。

在上面的基础上,我们来修改代码。
// com1.vue
<template>
<div>
<div @click="handleClick">com1</div>
<div>{{text}}</div>
</div>
</template>
<script>
export default {
name: 'Com1',
props: {
text: {
type: String,
default: ''
}
},
methods: {
handleClick () {
this.$emit('click', '我是子组件传过来的')
}
}
}
</script>
// App.vue
<template>
<div>
<Com1 text="我是 com1 的 props" @click="handleClick" />
<div>{{data}}</div>
</div>
</template>
<script>
import Com1 from './Com1'
export default {
name: 'app',
components: {
Com1
},
data () {
return {
data: ''
}
},
methods: {
handleClick (e) {
this.data = e
}
}
}
</script>
完成后,点击 " com1 " ,我们就能接收到 子组件传过来的东西了。

最土的就是层层传递,新建一个 Com2 .vue ,我们要做的是把 Com1 的文字传递到 Com2.vue。
// Com2.vue
<template>
<div>{{text}}</div>
</template>
<script>
export default {
name: 'Com2',
props: {
text: {
type: String,
default: ''
}
}
}
</script>
// Com1.vue
<template>
<div>
<div @click="handleClick">com1</div>
<div>{{text}}</div>
</div>
</template>
<script>
export default {
name: 'Com1',
props: {
text: {
type: String,
default: ''
}
},
methods: {
handleClick () {
this.$emit('click', '我是 Com1 传过来的 !!!')
}
}
}
</script>
// App.vue
<template>
<div>
<Com1 text="我是 com1 的 props" @click="handleClick" />
------------
<Com2 :text="data" />
</div>
</template>
<script>
import Com1 from './Com1'
import Com2 from './Com2'
export default {
name: 'app',
components: {
Com1,
Com2
},
data () {
return {
data: ''
}
},
methods: {
handleClick (e) {
this.data = e
}
}
}
</script>
再点击 ' com1 ' ,Com2.vue 里就接收到了我们从 Com1 传过去的东西

provide 和 inject主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。
我们继续修改刚才的那几个文件。
// App.vue
<template>
<div>
<Com1 text="我是 com1 的 props" @click="handleClick" />
</div>
</template>
<script>
import Com1 from './Com1'
export default {
name: 'app',
provide: {
text: '我是App.vue传过来的'
},
components: {
Com1
},
data () {
return {
data: '',
transitionName: ''
}
},
methods: {
handleClick (e) {
this.data = e
}
}
}
</script>
// Com1.vue
<template>
<div>
<div>com1</div>
<div>{{text}}</div>
------------
<Com2 />
</div>
</template>
<script>
import Com2 from './Com2'
export default {
name: 'Com1',
components: {
Com2
},
props: {
text: {
type: String,
default: ''
}
}
}
</script>
// Com2.vue
<template>
<div>Com2:{{text}}</div>
</template>
<script>
export default {
name: 'Com2',
inject: ['text']
}
</script>
修改后,我们直接通过在 App.vue 中 定义了 provide , 然后 直接传递到了 Com2 组件,在 Com2 里通过 inject 接收。虽然它是 Com1 的子组件,但是我们并没有使用 props 的方式层层传递下去。
其他通信方式
就要用到那些状态管理工具了Vuex
