vue3中的组件通信方式
文章类型:Vue
发布者:hp
发布时间:2024-11-22
在进行vue3项目开发时候,我们不可避免会涉及数据交互,比如父子组件通信,兄弟组件通信,后代组件通信,那么怎么来实现对应的功能呢,
1:Props(父组件像子组件传递数据)
父组件
<template>
<div>
<ChildComponent :childData="parentData" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentData = ref('这是来自父组件的数据');
</script>
子组件
<template>
<div>{{ childData }}</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
childData: String
});
</script>
2:Custom Events(子组件向父组件传递数据)
父组件
<template>
<div>
<ChildComponent @update:parentData="handleParentDataUpdate" />
<p>父组件接收到的数据:{{ parentReceivedData }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentReceivedData = ref('');
function handleParentDataUpdate(data) {
parentReceivedData.value = data;
}
</script>
子组件
<template>
<button @click="notifyParent">通知父组件</button>
</template>
<script setup>
import { defineEmits } from 'vue';
const emits = defineEmits(['update:parentData']);
function notifyParent() {
emits('update:parentData', '这是来自子组件的数据');
}
</script>
3:Provide / Inject(跨组件传递数据)
祖先组件
<template>
<div>
<DescendantComponent />
</div>
</template>
<script setup>
import { provide } from 'vue';
provide('ancestorData', '这是来自祖先组件的数据');
</script>
后代组件
<template>
<div>{{ ancestorData }}</div>
</template>
<script setup>
import { inject } from 'vue';
const ancestorData = inject('ancestorData', '默认值');
</script>
4:Refs(父组件访问子组件实例)
父组件
<template>
<div>
<ChildComponent ref="childRef" />
<button @click="accessChildMethod">调用子组件方法</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const childRef = ref(null);
function accessChildMethod() {
if (childRef.value) {
childRef.value.childMethod();
}
}
</script>
子组件
<script setup>
import { defineExpose } from 'vue';
function childMethod() {
console.log('子组件方法被调用');
}
defineExpose({
childMethod
});
</script>
5:Vuex/Pinia(状态管理),用于集中管理所有组件的共享状态。它们提供了全局状态存储和跨组件访问状态的能力,可以有效地管理这些状态,并保持应用的可维护性和可扩展性
6:v-mode进行父子组件双向数据绑定
父组件
<template>
<div>
<ChildComponent v-model:childData="parentData" />
<p>父组件的数据:{{ parentData }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentData = ref('初始数据');
</script>
子组件
<template>
<div>
<input v-model="localData" @input="updateValue" />
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
modelValue: String
});
const emit = defineEmits(['update:modelValue']);
const localData = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
});
function updateValue(event) {
// 这里通常不需要手动调用,因为v-model已经处理了
// 但如果需要基于输入值做进一步处理后再更新,可以在这里添加逻辑
}
</script>
7:使用三方库mitt或EventBus进行跨组件通信,(轻量级事件发射、订阅库)
npm install mitt
// eventBus.js
import mitt from 'mitt';
const emitter = mitt();
export default emitter;
//组件使用
// 发送事件的组件
<script setup>
import emitter from './eventBus';
function sendMessage() {
emitter.emit('message', 'Hello from anywhere!');
}
</script>
// 监听事件的组件
<script setup>
import { onMounted, onUnmounted } from 'vue';
import emitter from './eventBus';
onMounted(() => {
emitter.on('message', (msg) => {
console.log(msg); // 输出: Hello from anywhere!
});
});
onUnmounted(() => {
emitter.off('message'); // 清理事件监听,避免内存泄漏
});
</script>
1:父传子采用props,子传父defineEmits