props / emits
props只能是父组件向子组件进行传值,props使得父子组件之间形成了一个单向下行绑定,子组件的数据会随着父组件不断更新。props可以显示定义一个或一个以上的数据。props属性名规则:若在props中使用驼峰形式,模板中需要使用短横线的形式
子组件
<script setup>
defineProps({
message: {
type: String,
},
});
const emits = defineEmits(["update"]);
const sendMessageToParent = () => {
emits("update", "Hello from child");
};
</script>
<template>
<button @click="sendMessageToParent">{{ message }}</button>
</template>
父组件
<script setup>
import { ref } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
const parentMessage = ref("Hello from parent");
const updateMessage = (newMessage) => {
parentMessage.value = newMessage;
};
</script>
<template>
<HelloWorld :message="parentMessage" @update="updateMessage" />
</template>
project / inject
有一些多层级嵌套的组件,形成了一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。在这种情况下,如果仅使用 props 则必须将其沿着组件链逐级传递下去,这会非常麻烦。
project钩子用来发送数据或方法inject钩子用来接收数据或方法
祖先组件:
<script setup>
import { ref, provide } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
const parentMessage = ref("Hello from parent");
provide('message', parentMessage);
</script>
<template>
<HelloWorld />
</template>
父组件:
<script setup>
import TheWelcome from './TheWelcome.vue';
</script>
<template>
<TheWelcome />
</template>
子组件:
<script setup>
import { inject } from 'vue';
const message = inject('message');
</script>
<template>
<button>{{ message }}</button>
</template>
eventBus事件总线
eventBus事件总线适用于父子组件、非父子组件等之间的通信
创建事件中心管理组件之间的通信
// EventBus.js
import { ref } from 'vue';
const eventBus = ref(new Vue());
export default eventBus;
SiblingComponent1.vue
<script setup>
import eventBus from "./EventBus.js";
const sendDataToSibling = () => {
eventBus.value.$emit("custom-event", "Data from Sibling 1");
};
</script>
<template>
<button @click="sendDataToSibling">Send Data to Sibling 2</button>
</template>
SiblingComponent2.vue
<script>
import eventBus from './EventBus.js';
export default {
data() {
return {
receivedData: '',
};
},
created() {
// 监听来自事件总线的自定义事件
eventBus.value.$on('custom-event', (data) => {
this.receivedData = data;
});
},
};
</script>
<template>
<div>Received Data: {{ receivedData }}</div>
</template>
$attrs / $listeners
$attrs 和 $listeners 是用于访问父组件传递的属性和监听器的特殊属性。通常用于处理传递给子组件的未明确声明的属性和事件。
$attrs:
$attrs 包含了父组件传递给子组件但子组件没有声明的属性。这对于将属性传递到子组件的根元素或其他子元素非常有用。
<!-- ParentComponent.vue -->
<template>
<ChildComponent custom-attr="Custom Attribute" />
</template>
<!-- ChildComponent.vue -->
<template>
<p>{{ $attrs.custom-attr }}</p>
</template>
在上面的示例中,custom-attr 属性被传递给了子组件,但子组件没有明确声明它。子组件可以通过 $attrs 访问这个属性。
$listeners:
$listeners 包含了父组件传递给子组件的事件监听器。
<!-- ParentComponent.vue -->
<template>
<ChildComponent @custom-event="handleEvent" />
</template>
<!-- ChildComponent.vue -->
<template>
<button @click="$listeners['custom-event']('Data from Child')">Trigger Event</button>
</template>
在上面的示例中,custom-event 事件监听器被传递给了子组件,子组件可以通过 $listeners 来触发该事件。