Component通信实战总结:从基础到高级的全面解析与避坑指南

FSD-保霞 框架 阅读 2,702
赞 46 收藏
二维码
手机扫码查看
反馈

组件通信又踩坑了,这次是父子组件传值

最近在做一个项目,遇到了一个挺头疼的问题:父子组件之间传值。这个问题其实挺常见的,但就是折腾了半天才搞定。

Component通信实战总结:从基础到高级的全面解析与避坑指南

问题来了,父子组件传值不对劲

我有一个父组件 ParentComponent,里面有个按钮,点击按钮后会触发一个方法,这个方法需要更新子组件 ChildComponent 的状态。本来以为很简单,直接用 props 传值就行了,结果发现没那么简单。

排查过程,各种尝试

一开始我是这么写的:

// ParentComponent.vue
<template>
  <div>
    <button @click="updateChild">Update Child</button>
    <ChildComponent :childData="parentData" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentData: 'Initial Data'
    };
  },
  methods: {
    updateChild() {
      this.parentData = 'Updated Data';
    }
  }
};
</script>

然后在子组件里接收:

// ChildComponent.vue
<template>
  <div>
    {{ childData }}
  </div>
</template>

<script>
export default {
  props: {
    childData: String
  }
};
</script>

按理说这样应该没问题,但子组件的状态并没有更新。这里我踩了个坑,因为 Vue 的响应式系统有时候会有点诡异。

换种方式,试试事件总线

后来试了下用事件总线来解决这个问题。Vue 3 里可以用 mitt 或者 vue-emit 这样的库来实现事件总线。我选择了 mitt,因为它简单好用。

npm install mitt

然后在主应用文件中引入并初始化:

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import mitt from 'mitt';

const emitter = mitt();

const app = createApp(App);
app.config.globalProperties.$emitter = emitter;
app.mount('#app');

在父组件里发送事件:

// ParentComponent.vue
<template>
  <div>
    <button @click="updateChild">Update Child</button>
    <ChildComponent />
  </div>
</template>

<script>
export default {
  methods: {
    updateChild() {
      this.$emitter.emit('update-child', 'Updated Data');
    }
  }
};
</script>

在子组件里监听事件:

// ChildComponent.vue
<template>
  <div>
    {{ childData }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      childData: 'Initial Data'
    };
  },
  created() {
    this.$emitter.on('update-child', (data) => {
      this.childData = data;
    });
  }
};
</script>

这样终于解决了问题,子组件的状态能够正确更新了。

技术细节和原理

这里稍微聊聊为什么最初的方法不行。Vue 的响应式系统是基于数据的依赖追踪机制,当你通过 props 传递数据时,如果父组件的数据发生变化,Vue 会自动更新子组件的状态。但有时候由于一些原因(比如缓存、优化等),这种机制可能会失效。

而使用事件总线则是一种更直接的方式,通过事件来显式地通知子组件进行状态更新。这种方式虽然有点绕,但在某些情况下确实更可靠。

总结一下,踩坑后的经验

以上是我在这次开发中遇到的关于父子组件通信的问题和解决方案。事件总线虽然不是最优解,但在这个场景下确实有效。如果你有更好的方案,欢迎在评论区交流。

这个技巧的拓展用法还有很多,后续会继续分享这类博客。希望对你有帮助!

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论