返回
Vue 组件间通信的奇妙世界:六种方式深入实践指南
前端
2023-09-24 15:24:47
在 Vue.js 中,组件是构建用户界面的基本单位。组件之间的数据和事件是如何通信的呢?本文将介绍 Vue 组件间通信的六种方式,包括父子组件通信、兄弟组件通信、隔代组件通信、事件总线、状态管理和 provide/inject。
1. 父子组件通信
父子组件通信是最常见的一种组件通信方式。父组件可以向子组件传递数据,也可以监听子组件发出的事件。
传递数据
父组件可以通过 props 向子组件传递数据。props 是只读的,子组件不能修改 props 的值。
<!-- 父组件 -->
<template>
<child-component :message="message" />
</template>
<script>
export default {
data() {
return {
message: 'Hello, Vue!'
}
}
}
</script>
<!-- 子组件 -->
<template>
<p>{{ message }}</p>
</template>
<script>
export default {
props: ['message']
}
</script>
监听事件
子组件可以通过 $emit 方法向父组件发出事件。父组件可以通过 v-on 指令监听子组件发出的事件。
<!-- 父组件 -->
<template>
<child-component @message="handleMessage" />
</template>
<script>
export default {
methods: {
handleMessage(message) {
console.log(message)
}
}
}
</script>
<!-- 子组件 -->
<template>
<button @click="handleClick">点击我</button>
</template>
<script>
export default {
methods: {
handleClick() {
this.$emit('message', 'Hello, Vue!')
}
}
}
</script>
2. 兄弟组件通信
兄弟组件通信是指两个没有直接父子关系的组件之间的通信。
事件总线
事件总线是一种组件间通信的方式,它允许组件通过一个中央事件总线发布和订阅事件。
<!-- 主组件 -->
<template>
<component-a @message="handleMessage" />
<component-b @message="handleMessage" />
</template>
<script>
export default {
data() {
return {
message: ''
}
},
methods: {
handleMessage(message) {
this.message = message
}
}
}
</script>
<!-- 组件 A -->
<template>
<button @click="handleClick">点击我</button>
</template>
<script>
export default {
methods: {
handleClick() {
this.$emit('message', 'Hello, Vue!')
}
}
}
</script>
<!-- 组件 B -->
<template>
<p>{{ message }}</p>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
状态管理
状态管理是一种组件间通信的方式,它允许组件共享一个全局的状态。
<!-- 主组件 -->
<template>
<component-a />
<component-b />
</template>
<script>
import { createStore } from 'vuex'
export default {
data() {
return {
store: createStore({
state: {
message: ''
},
mutations: {
setMessage(state, message) {
state.message = message
}
}
})
}
}
}
</script>
<!-- 组件 A -->
<template>
<button @click="handleClick">点击我</button>
</template>
<script>
export default {
methods: {
handleClick() {
this.$store.commit('setMessage', 'Hello, Vue!')
}
}
}
</script>
<!-- 组件 B -->
<template>
<p>{{ $store.state.message }}</p>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
3. 隔代组件通信
隔代组件通信是指祖先组件和孙子组件之间的通信。
provide/inject
provide/inject 是一种组件间通信的方式,它允许祖先组件向其所有子孙组件提供数据。
<!-- 祖先组件 -->
<template>
<child-component />
</template>
<script>
export default {
provide() {
return {
message: 'Hello, Vue!'
}
}
}
</script>
<!-- 子组件 -->
<template>
<grandchild-component />
</template>
<script>
export default {
inject: ['message']
}
</script>
<!-- 孙子组件 -->
<template>
<p>{{ message }}</p>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
4. props + events
props + events 是另一种常见的组件间通信方式,它结合了 props 和事件总线。
props
props 是只读的,子组件不能修改 props 的值。
<!-- 父组件 -->
<template>
<child-component :message="message" @message="handleMessage" />
</template>
<script>
export default {
data() {
return {
message: 'Hello, Vue!'
}
},
methods: {
handleMessage(message) {
console.log(message)
}
}
}
</script>
<!-- 子组件 -->
<template>
<p>{{ message }}</p>
<button @click="handleClick">点击我</button>
</template>
<script>
export default {
props: ['message'],
methods: {
handleClick() {
this.$emit('message', 'Hello, Vue!')
}
}
}
</script>
5. parent/refs
parent 和 refs 是 Vue 中内置的两个属性,它们可以用来访问父组件和子组件。
$parent
$parent 属性可以用来访问父组件。
<!-- 子组件 -->
<template>
<p>{{ $parent.message }}</p>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
$refs
$refs 属性可以用来访问子组件。
<!-- 父组件 -->
<template>
<child-component ref="child" />
</template>
<script>
export default {
data() {
return {
message: 'Hello, Vue!'
}
},
methods: {
handleMessage() {
console.log(this.$refs.child.message)
}
}
}
</script>
<!-- 子组件 -->
<template>
<p>{{ message }}</p>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
6. 插槽
插槽是一种组件间通信的方式,它允许父组件向子组件提供内容。
<!-- 父组件 -->
<template>
<child-component>
<p>Hello, Vue!</p>
</child-component>
</template>
<script>
export default {
data() {
return {
message: 'Hello, Vue!'
}
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<slot />
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
总结
Vue 组件间通信的六种方式各有优缺点,具体使用哪种方式取决于项目的具体需求。