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>
<button @click="notifyParent">通知父组件</button>
</template>
<script setup>
import { defineEmits } from 'vue';
const emits = defineEmits(['update:parentData']);
function notifyParent() {
emits('update:parentData', '这是来自子组件的数据');
}
</script>
父组件:
<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>
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>
子组件(ChildComponent.vue):
<script setup>
import { defineExpose } from 'vue';
function childMethod() {
console.log('子组件方法被调用');
}
defineExpose({
childMethod
});
</script>
5 、Vuex / Pinia(状态管理)
Vuex
和 Pinia
是 Vue 应用的状态管理模式和库
,用于集中管理所有组件的共享状态。它们提供了全局状态存储和跨组件访问状态的能力。
6、 使用v-model进行父子组件间的双向数据绑定
父组件:
<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>
子组件(ChildComponent.vue):
<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) {
console.log(event,"更新后的数据");
}
</script>
7、使用mitt或EventBus进行跨组件通信
mitt是一个轻量级的事件发射/订阅库,它可以用作Vue应用中的全局事件总线,实现跨组件通信。虽然Vue 3没有内置EventBus,但你可以通过安装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);
});
});
onUnmounted(() => {
emitter.off('message');
});
</script>