编辑
2023-08-26
Vue
00
请注意,本文编写于 180 天前,最后修改于 180 天前,其中某些信息可能已经过时。

目录

Props
自定义事件
事件总线(Event Bus)
Vuex
$parent 和 $children
依赖注入
$attrs 和 $listeners
插槽(Slots)
$refs
localStorage或sessionStorage
总结

Vue应用开发中,组件通信是一个重要的话题。不同的组件可能需要在不同的情况下进行数据传递和交互。Vue提供了多种方式来实现组件通信,每种方式都有其适用的场景。本文将详细介绍Vue中实现组件通信的各种方式,并为每种方式提供通俗易懂的代码示例。

Props

Props是父组件向子组件传递数据的一种方式。子组件通过在声明中指定props属性来接收父组件传递的数据。

html
<!-- ParentComponent.vue --> <template> <ChildComponent message="Hello from parent!" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent, }, }; </script> <!-- ChildComponent.vue --> <template> <div>{{ message }}</div> </template> <script> export default { props: ['message'], }; </script>

自定义事件

子组件可以使用$emit触发一个自定义事件,父组件通过在子组件上使用v-on监听该事件并执行相应的方法。

html
<!-- ChildComponent.vue --> <template> <button @click="sendMessage">Send Message to Parent</button> </template> <script> export default { methods: { sendMessage() { this.$emit('message-sent', 'Hello from child!'); }, }, }; </script> <!-- ParentComponent.vue --> <template> <ChildComponent @message-sent="handleMessage" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent, }, methods: { handleMessage(message) { console.log(message); // Output: "Hello from child!" }, }, }; </script>

事件总线(Event Bus)

事件总线是一个空的Vue实例,可以用于在任何组件间发布和订阅事件。

html
<!-- EventBus.js --> import Vue from 'vue'; export const eventBus = new Vue(); <!-- FirstComponent.vue --> <template> <button @click="sendMessage">Send Message to SecondComponent</button> </template> <script> import { eventBus } from './EventBus.js'; export default { methods: { sendMessage() { eventBus.$emit('message-sent', 'Hello from first component!'); }, }, }; </script> <!-- SecondComponent.vue --> <template> <div>{{ message }}</div> </template> <script> import { eventBus } from './EventBus.js'; export default { data() { return { message: '', }; }, created() { eventBus.$on('message-sent', (message) => { this.message = message; }); }, }; </script>

Vuex

VuexVue的状态管理库,用于在不同组件间共享状态。

html
<!-- store/index.js --> 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; }, }, }); <!-- FirstComponent.vue --> <template> <button @click="updateMessage">Update Message in SecondComponent</button> </template> <script> import { mapMutations } from 'vuex'; export default { methods: { ...mapMutations(['updateMessage']), updateMessage() { this.updateMessage('Hello from first component!'); }, }, }; </script> <!-- SecondComponent.vue --> <template> <div>{{ message }}</div> </template> <script> import { mapState } from 'vuex'; export default { computed: { ...mapState(['message']), }, }; </script>

parentparent 和 children

Vue提供了$parent$children属性来访问父组件和子组件的实例。

html
<!-- ParentComponent.vue --> <template> <div> <ChildComponent /> </div> </template> <!-- ChildComponent.vue --> <template> <button @click="sendMessage">Send Message to Parent</button> </template> <script> export default { methods: { sendMessage() { this.$parent.message = 'Hello from child!'; }, }, }; </script>

依赖注入

依赖注入是一种高级的通信方式,适用于祖先组件向后代组件传递数据,而不需要显式地通过props传递。

html
<!-- AncestorComponent.vue --> <template> <DescendantComponent /> </template> <script> import { provide } from 'vue'; import DescendantComponent from './DescendantComponent.vue'; export default { components: { DescendantComponent, }, setup() { provide('message', 'Hello from ancestor!'); }, }; </script> <!-- DescendantComponent.vue --> <template> <div>{{ message }}</div> </template> <script> import { inject } from 'vue'; export default { setup() { const message = inject('message'); return { message, }; }, }; </script>

attrsattrs 和 listeners

$attrs$listeners 允许将父组件中非 prop 特性和事件传递给子组件,用于更灵活的组件封装。

html
<!-- ParentComponent.vue --> <template> <ChildComponent title="Hello" @custom-event="handleEvent" /> </template> <!-- ChildComponent.vue --> <template> <div> <h1>{{ title }}</h1> <button @click="$emit('custom-event', 'Custom Event')">Click</button> </div> </template> <script> export default { props: ['title'], }; </script>

插槽(Slots)

插槽允许父组件向子组件传递内容,而不仅仅是数据。

html
<!-- ParentComponent.vue --> <template> <ChildComponent> <p>Slot content from parent</p> </ChildComponent> </template> <!-- ChildComponent.vue --> <template> <div> <slot></slot> </div> </template>

$refs

$refs 允许父组件访问子组件的实例,从而进行直接通信。

html
<!-- ParentComponent.vue --> <template> <div> <ChildComponent ref="childRef" /> <button @click="sendMessageToChild">Send Message to Child</button> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent, }, methods: { sendMessageToChild() { this.$refs.childRef.receiveMessage('Hello from parent!'); }, }, }; </script> <!-- ChildComponent.vue --> <template> <div>{{ message }}</div> </template> <script> export default { data() { return { message: '', }; }, methods: { receiveMessage(message) { this.message = message; }, }, }; </script>

localStorage或sessionStorage

浏览器缓存在一定程序上也可以帮助我们实现组件通信,甚至跨页面、跨窗口通信,但是在Vue项目中有很多更优秀的通信方式,不是很建议使用localStoragesessionStorage来实现。

js
// 在一个页面中存储数据 localStorage.setItem('message', 'Hello from localStorage'); // 在另一个页面中获取数据 const message = localStorage.getItem('message'); console.log(message); // "Hello from localStorage"

总结

组件通信是我们日常开发中最常见的功能,可以这样说,有组件的地方就有组件通信的需求,而现在所有框架都朝着组件化、工程化的方向发展,所以组件通信是我们必须掌握的。

上述内容详细介绍了Vue中实现组件通信的多种方式,提供了基本的代码示例。它们有各自的使用场景,大家可以根据不同的场景和需求,选择合适的通信方式可以让你的Vue应用更加高效和可维护。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:CreatorRay

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!