> 文章列表 > vue组件间如何实现通信

vue组件间如何实现通信

vue组件间如何实现通信

组件通信方式

在 Vue2 中,有以下几种方式实现组件通信:

  1. props/ e m i t :父组件通过 p r o p s 向子组件传递数据,子组件通过 emit:父组件通过props向子组件传递数据,子组件通过 emit:父组件通过props向子组件传递数据,子组件通过emit 事件向父组件发送消息。

  2. p a r e n t / parent/ parent/children:通过 p a r e n t 和 parent和 parentchildren 访问父组件和子组件的实例。

  3. r e f s :通过 refs:通过 refs:通过refs 获取子组件的引用,并直接调用子组件中的方法或属性。

  4. eventBus:使用一个独立的 Vue 实例作为事件总线,通过 e m i t 和 emit和 emiton 触发和监听自定义事件。

  5. Vuex:当需要多个组件共享状态时,可以使用 Vuex 来管理全局状态。

在 Vue3 中,由于采用了 Composition API,组件通信变得更加灵活和直观。以下是几种常用的方法:

  1. props/context:通过 props 将数据从父组件传递给子组件,在子组件中使用 setup 函数中的 context 对象访问父组件的属性或方法。

  2. provide/inject:与 props/context 类似,provide/inject 同样用于父子组件之间的通信,但是它可以让祖先组件向所有后代组件注入数据,而不仅仅是直接后代组件。

  3. ref/teleport:通过 ref 获取组件的引用,并使用 teleport 将组件挂载到指定的 DOM 节点上。

  4. EventBus/Emitter:与 Vue2 类似,可以使用一个独立的 Vue 实例作为事件总线,在组件之间发送和接收自定义事件。

  5. Vuex 4.x: 可以使用 Vuex 来管理全局状态,但是在 Vue3 中有了更好的支持,使用新的 API 替换了旧 API,并且提供了更好的类型安全性和开箱即用的响应式需求。

总体而言,Vue2 和 Vue3 中的组件通信方法大同小异,但是由于 Vue3 采用 Composition API,使得组件通信更加方便和灵活。

vue2 组件通信 demo

以下是其中几种常见的方式及示例代码:

  1. 父子组件通信:父组件通过 props 向子组件传递数据,子组件通过 $emit 触发事件通知父组件。

父组件:

<template><child-component :message="parentMessage" @update-message="updateParentMessage"></child-component>
</template><script>
import ChildComponent from './ChildComponent.vue'export default {components: {ChildComponent},data() {return {parentMessage: ''}},methods: {updateParentMessage(message) {this.parentMessage = message}}
}
</script>

子组件:

<template><div>{{ message }}<button @click="onClick">Update Message</button></div>
</template><script>
export default {props: {message: String},methods: {onClick() {const newMessage = 'New message from child component'this.$emit('update-message', newMessage)}}
}
</script>
  1. 兄弟组件通信:通过一个空的 Vue 实例作为中央事件总线(event bus),将其作为一个全局的事件管理器来实现兄弟组件之间的通信。

事件总线:

import Vue from 'vue'
export default new Vue()

组件 A:

<template><div>{{ message }}<button @click="onClick">Update Message</button></div>
</template><script>
import EventBus from './EventBus'export default {data() {return {message: ''}},methods: {onClick() {const newMessage = 'New message from component A'EventBus.$emit('update-message', newMessage)}},created() {EventBus.$on('update-message', (message) => {this.message = message})}
}
</script>

组件 B:

<template><div>{{ message }}</div>
</template><script>
import EventBus from './EventBus'export default {data() {return {message: ''}},created() {EventBus.$on('update-message', (message) => {this.message = message})}
}
</script>
  1. Vuex 状态管理:通过 Vuex 实现全局状态管理,各组件共享同一个状态。

store:

import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {message: ''},mutations: {updateMessage(state, message) {state.message = message}}
})

组件 A:

<template><div>{{ message }}<button @click="onClick">Update Message</button></div>
</template><script>
export default {computed: {message() {return this.$store.state.message}},methods: {onClick() {const newMessage = 'New message from component A'this.$store.commit('updateMessage', newMessage)}}
}
</script>

组件 B:

<template><div>{{ message }}</div>
</template><script>
export default {computed: {message() {return this.$store.state.message}}
}
</script>

Vue3 组件通信

Vue 3 提供了多种组件通信方式,以下是其中一些常用的示例:

  1. props 和 emit

父组件通过 props 向子组件传递数据,子组件通过 emit 方法向父组件发送事件。

父组件 template:

<template><child-component :message="msg" @send-message="handleMessage"></child-component>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {msg: 'Hello World'}},methods: {handleMessage(message) {console.log(message);}}
}
</script>

子组件 template:

<template><div>{{ message }}<button @click="sendMessage">Send Message</button></div>
</template><script>
export default {props: {message: String},methods: {sendMessage() {this.$emit('send-message', 'Hi Parent!');}}
}
</script>
  1. provide 和 inject

provide 和 inject 可以在祖先组件提供数据,然后在后代组件中使用。

祖先组件:

<template><grand-child-component></grand-child-component>
</template><script>
import { provide } from 'vue';export default {setup() {const name = 'John';provide('name', name);return {};}
}
</script>

后代组件:

<template><div>{{ name }}</div>
</template><script>
import { inject } from 'vue';export default {setup() {const name = inject('name');return {name}}
}
</script>
  1. $attrs 和 $listeners

a t t r s 包含了父组件传递给子组件的所有属性, attrs 包含了父组件传递给子组件的所有属性, attrs包含了父组件传递给子组件的所有属性,listeners 包含了父组件在子组件上绑定的所有事件监听器。

子组件:

<template><div v-bind="$attrs" v-on="$listeners">{{ message }}</div>
</template><script>
export default {props: {message: String},
}
</script>

父组件 template:

<template><child-component message="Hello World" class="text-red" @click="handleClick"></child-component>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {handleClick() {console.log('Clicked!');}}
}
</script>