vue组件通信 at
时间: 2025-05-03 18:49:12 浏览: 29
### Vue 组件间的通信方法
Vue 提供了多种组件间通信的方式,适用于不同的场景和需求。以下是常见的 Vue 组件通信方法及其实现技巧:
#### 1. **Props 和 $emit**
`props` 是父组件向子组件传递数据的主要方式,而 `$emit` 则用于子组件向父组件发送事件通知。
- 父组件通过 `props` 将数据传递到子组件中[^1]。
- 子组件可以通过调用 `$emit` 方法触发自定义事件,并将数据回传给父组件[^2]。
示例代码如下:
```vue
<!-- ParentComponent.vue -->
<template>
<ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
parentMessage: 'Hello from Parent',
};
},
methods: {
handleChildEvent(data) {
console.log('Data received from child:', data);
}
}
};
</script>
```
```vue
<!-- ChildComponent.vue -->
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: ['message'],
mounted() {
this.$emit('childEvent', 'Hello from Child');
}
};
</script>
```
---
#### 2. **Provide 和 Inject**
`provide/inject` 主要用于跨多层嵌套的父子组件之间共享状态,适合全局配置或深层嵌套的情况。
示例代码如下:
```javascript
// ParentComponent.vue
export default {
provide() {
return {
sharedState: this.sharedState,
};
},
data() {
return {
sharedState: 'Shared Data',
};
},
};
// DeeplyNestedChildComponent.vue
export default {
inject: ['sharedState'],
created() {
console.log(this.sharedState); // 输出 "Shared Data"
},
};
```
---
#### 3. **v-model (双向绑定)**
`v-model` 实现了父子组件之间的双向绑定,通常用于表单输入控件。
示例代码如下:
```vue
<!-- ParentComponent.vue -->
<template>
<CustomInput v-model="inputValue" />
</template>
<script>
import CustomInput from './CustomInput.vue';
export default {
components: { CustomInput },
data() {
return {
inputValue: '',
};
},
};
</script>
```
```vue
<!-- CustomInput.vue -->
<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>
<script>
export default {
props: ['modelValue'],
};
</script>
```
---
#### 4. **Vuex (集中式状态管理)**
对于复杂的大型项目,推荐使用 Vuex 来统一管理和分发状态。
示例代码如下:
```javascript
// store.js
import { createStore } from 'vuex';
const store = createStore({
state: {
count: 0,
},
mutations: {
increment(state) {
state.count++;
},
},
});
export default store;
```
```vue
<!-- AnyComponent.vue -->
<template>
<button @click="increment">Increment Count</button>
{{ count }}
</template>
<script>
export default {
computed: {
count() {
return this.$store.state.count;
},
},
methods: {
increment() {
this.$store.commit('increment');
},
},
};
</script>
```
---
#### 5. **Mitt 或 Event Bus**
如果不想引入 Vuex,可以使用轻量级库 Mitt 创建一个简单的事件总线来处理非父子关系的组件通信。
示例代码如下:
```javascript
// eventBus.js
import mitt from 'mitt';
const emitter = mitt();
export default emitter;
// ComponentA.vue
emitter.emit('custom-event', payload);
// ComponentB.vue
emitter.on('custom-event', handlerFunction);
```
---
#### 6. **Expose/Ref**
在组合式 API 中,`ref` 可以用来访问子组件实例中的公开属性或方法,配合 `defineExpose` 使用。
示例代码如下:
```vue
<!-- ParentComponent.vue -->
<template>
<ChildComponent ref="childRef" />
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const childRef = ref(null);
function callChildMethod() {
childRef.value?.publicMethod();
}
</script>
```
```vue
<!-- ChildComponent.vue -->
<script setup>
defineExpose({
publicMethod() {},
});
</script>
```
---
#### 7. **Attrs 和 Listeners**
当某些属性未被声明为 `props` 时,它们会自动成为 `attrs` 并向下传播;类似的还有 `$listeners`,不过在 Vue 3 中已被移除并替换为 `v-on`。
示例代码如下:
```vue
<!-- GrandParentComponent.vue -->
<template>
<ParentComponent customAttr="test" @customEvent="handleCustomEvent" />
</template>
```
```vue
<!-- ParentComponent.vue -->
<template>
<ChildComponent v-bind="$attrs" v-on="$listeners" />
</template>
<script>
export default {
inheritAttrs: false, // 防止 attrs 被挂载到根节点上
};
</script>
```
---
#### 总结
以上列举了几种主流的 Vue 组件通信方式,每种都有其适用范围和特点。开发者应根据具体业务需求选择合适的方案。
阅读全文
相关推荐




















