Vue 2 通信方式
1. Props 和 Events(父子组件通信)
这是 Vue 中最基础的通信方式,适用于父子组件之间的数据传递。
Props:父组件向子组件传递数据
- 父组件通过
props将数据传递给子组件。 - 子组件通过声明
props来接收数据。
示例代码:
<!-- 父组件 -->
<template>
<ChildComponent :message="parentMessage" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
data() {
return {
parentMessage: 'Hello from Parent'
};
},
components: { ChildComponent }
};
</script>
<!-- 子组件 -->
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true
}
}
};
</script>
Events:子组件向父组件传递数据
- 子组件通过
$emit触发自定义事件,将数据传递给父组件。 - 父组件通过监听事件来接收数据。
示例代码:
<!-- 子组件 -->
<template>
<button @click="sendToParent">Send Message to Parent</button>
</template>
<script>
export default {
methods: {
sendToParent() {
this.$emit('child-event', 'Hello from Child');
}
}
};
</script>
<!-- 父组件 -->
<template>
<ChildComponent @child-event="handleChildEvent" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
methods: {
handleChildEvent(message) {
console.log(message); // 输出:Hello from Child
}
}
};
</script>
2. Vuex(全局状态管理)
当项目规模较大时,使用 Vuex 可以集中管理全局状态,适用于跨层级组件通信或多个组件共享状态。
核心概念:
- State:存储全局状态。
- Getters:从 State 中派生出一些状态。
- Mutations:同步修改 State。
- Actions:异步操作,最终调用 Mutations 修改 State。
示例代码:
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
}
}
});
<!-- 组件中使用 Vuex -->
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
export default {
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.commit('increment');
}
}
};
</script>
3. Event Bus(事件总线)
适用于非父子组件之间的通信,但不推荐在大型项目中使用,因为容易导致代码难以维护。
实现方式:
- 创建一个空的 Vue 实例作为事件总线。
- 使用
$emit发送事件,使用$on监听事件。
示例代码:
// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
<!-- 组件 A -->
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
import { EventBus } from './eventBus';
export default {
methods: {
sendMessage() {
EventBus.$emit('message', 'Hello from Component A');
}
}
};
</script>
<!-- 组件 B -->
<template>
<div>{{ message }}</div>
</template>
<script>
import { EventBus } from './eventBus';
export default {
data() {
return {
message: ''
};
},
created() {
EventBus.$on('message', (msg) => {
this.message = msg;
});
}
};
</script>
4. Provide / Inject(祖先与后代组件通信)
适用于祖先组件向深层嵌套的后代组件传递数据,而无需逐层传递 props。
实现方式:
- 祖先组件通过
provide提供数据。 - 后代组件通过
inject注入数据。
示例代码:
<!-- 祖先组件 -->
<template>
<ChildComponent />
</template>
<script>
export default {
provide() {
return {
sharedData: 'Hello from Ancestor'
};
}
};
</script>
<!-- 后代组件 -->
<template>
<div>{{ sharedData }}</div>
</template>
<script>
export default {
inject: ['sharedData']
};
</script>
5. parent / $children
$refs:访问子组件实例
- 通过
ref属性为子组件设置引用名,父组件可以通过this.$refs访问子组件实例。
children:直接访问父/子组件
$parent用于访问父组件实例。$children用于访问子组件实例数组。
注意: 这种方式会破坏组件的封装性,应谨慎使用。
总结
| 通信方式 | 适用场景 |
|---|---|
| Props 和 Events | 父子组件通信 |
| Vuex | 全局状态管理,跨层级组件通信 |
| Event Bus | 非父子组件通信(小型项目) |
| Provide / Inject | 祖先与深层后代组件通信 |
| parent | 直接访问组件实例(不推荐频繁使用) |
选择合适的通信方式可以提高代码的可维护性和可读性。对于小型项目,Props 和 Event Bus 是常用的选择;而对于大型项目,建议使用 Vuex 或 Provide/Inject 来管理复杂的状态和通信逻辑。