目录
[1. Props(父传子)](#1. Props(父传子))
[2. emit(子传父)](#2. emit(子传父))
[3. .sync 修饰符(双向绑定)](#3. .sync 修饰符(双向绑定))
[4. Provide / Inject(祖孙组件通信)](#4. Provide / Inject(祖孙组件通信))
[5. EventBus(兄弟/跨组件通信)](#5. EventBus(兄弟/跨组件通信))
[6. Pinia / Vuex(全局状态管理)](#6. Pinia / Vuex(全局状态管理))
[7. parent/parent/children / refs(直接访问)](#7. parent/parent/children / refs(直接访问))
[8. attrs/attrs/listeners(跨代通信)](#8. attrs/attrs/listeners(跨代通信))
[9. v-model(双向绑定)](#9. v-model(双向绑定))
[10. root(访问根实例)](#10. root(访问根实例))
[11. ref(访问子组件)](#11. ref(访问子组件))
[12. mitt(事件总线)](#12. mitt(事件总线))
1. **Props(父传子)**
-
优点:简单直接,符合单向数据流原则,易于理解和维护。
-
缺点:层级过深时,传递数据会变得复杂。
-
使用实例:
<child-component :user="currentUser" /> <script> export default { props: { user: { type: Object, required: true } } } </script>
2. **$emit(子传父)**
-
优点:用于子组件向父组件传递数据,使用简单,非常常见。
-
缺点:如果层级过深,需层层传递,容易造成代码冗余。
-
使用实例:
<script> export default { methods: { handleClick() { this.$emit('user-updated', { name: '新名字' }); } } } </script><child-component @user-updated="handleUpdate" />
3. **.sync 修饰符(双向绑定)**
-
优点:简化了双向绑定的写法,看起来更简洁。
-
缺点:Vue 3 中已被废弃,不推荐使用。
-
使用实例
<child-component :name.sync="userName" /> <script> export default { props: ['name'], methods: { updateName() { this.$emit('update:name', '新名字'); } } } </script>
4. **Provide / Inject(祖孙组件通信)**
-
优点:适用于跨层级组件通信,无需逐层传递 props。
-
缺点:非响应式,不适用于复杂状态管理。
-
使用实例:
<script> export default { provide() { return { user: this.currentUser }; } } </script> <script> export default { inject: ['user'] } </script>
5. **EventBus(兄弟/跨组件通信)**
-
优点:适用于任意组件间通信,使用简单。
-
缺点:难以维护,容易造成内存泄漏,不推荐在大型项目中使用。
-
使用实例:
// eventBus.js
import Vue from 'vue';
export default new Vue();// 组件A
EventBus.$emit('update-user', data);// 组件B
EventBus.$on('update-user', (data) => { ... });
6. **Pinia / Vuex(全局状态管理)**
-
优点:适合管理全局状态,便于维护和调试。
-
缺点:对于简单通信可能显得"重量级"。
-
使用实例:
// store.js
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({ name: '' }),
actions: {
updateName(name) {
this.name = name;
}
}
});// 组件中使用
const store = useUserStore();
store.updateName('张三');
7. **parent/parent/children / $refs(直接访问)**
-
优点:直接访问组件实例,适合操作子组件方法或数据。
-
缺点:破坏组件封装性,不易维护。
-
使用实例:
<child-component ref="childRef" />this.$refs.childRef.someMethod();
8. **attrs/attrs/listeners(跨代通信)**
-
优点:适合跨层级传递 props 和事件。
-
缺点 :需配合
inheritAttrs: false使用。 -
使用实例:
<child-component :title="title" @click="handleClick" />
<grand-child v-bind="$attrs" v-on="$listeners" />
9. **v-model(双向绑定)**
-
优点:简化了父子组件的双向数据绑定。
-
缺点 :需配合
defineProps和defineEmits使用(Vue 3)。 -
使用实例:
<child-component v-model="message" /> <script setup> const props = defineProps(['modelValue']); const emit = defineEmits(['update:modelValue']);const updateMessage = () => {
emit('update:modelValue', '新消息');
};
</script>
10. **$root(访问根实例)**
-
优点:可以访问根组件实例,适合全局状态访问。
-
缺点:容易导致代码耦合,不推荐滥用。
-
使用实例:
this.$root.someGlobalData = '数据';
11. **ref(访问子组件)**
-
优点:直接访问子组件实例,适合调用子组件方法。
-
缺点:破坏组件封装性。
-
使用实例:
<child-component ref="child" />this.$refs.child.someMethod();
12. **mitt(事件总线)**
-
优点:适用于任意组件通信,可替代 EventBus。
-
缺点:需手动管理事件监听,防止内存泄漏。
-
使用实例:
// mitt.js
import mitt from 'mitt';
const emitter = mitt();
export default emitter;// 组件A
emitter.emit('update-user', data);// 组件B
emitter.on('update-user', (data) => { ... });