props 通信注意:props传递的数据是只读的,子组件修改,不会影响父组件
props在子组件中使用 props 选项来定义要接收的属性
- // 子组件
- export default {
- props: {
- message: String
- }
- }
在父组件中使用子组件时,通过将属性绑定到子组件的属性名来传递数据。
- // 父组件
- <child-component :message="parentMessage">child-component>
-
- <script>
- import ChildComponent from './ChildComponent.vue';
-
- export default {
- components: {
- ChildComponent
- },
- data() {
- return {
- parentMessage: 'Hello from parent!'
- };
- }
- }
- script>
- // 子组件
- <div>{{ message }}div>
-
- <script>
- export default {
- props: {
- message: String
- }
- }
- script>
在 Vue 3 中,props 的使用方式与 Vue 2 类似,但有一些额外的特性,如默认值和类型校验的语法略有不同。
- // 子组件
- const props = defineProps({
- message: String
- });
-
- //或者
- const props = defineProps(['message']);
- // 父组件
- <child-component :message="parentMessage">child-component>
-
- <script setup>
- import ChildComponent from './ChildComponent.vue';
-
- const parentMessage=ref('Hello from parent!')
- script>
- // 子组件
- <div>{{ props.message }}div>
-
- <script setup>
- const props = defineProps({
- message: String
- });
-
- //或者
- const props = defineProps(['message']);
-
- script>
在子组件中,使用 $emit 方法触发一个自定义事件。
- // 子组件
- <button @click="emitCustomEvent">触发事件button>
-
- <script>
- export default {
- methods: {
- emitCustomEvent() {
- this.$emit('custom-event-name', eventData);
- }
- }
- }
- script>
在父组件中,通过在子组件上使用 v-on(或简写为 @)来监听自定义事件。
- // 父组件
- <child-component @custom-event-name="handleCustomEvent">child-component>
-
- <script>
- import ChildComponent from './ChildComponent.vue';
-
- export default {
- components: {
- ChildComponent
- },
- methods: {
- handleCustomEvent(eventData) {
- // 处理自定义事件触发的逻辑
- }
- }
- }
- script>
在子组件中,首先,我们导入了 defineEmits 函数,然后使用它来定义可触发的自定义事件,就像之前的示例一样。接下来,我们创建了 emitCustomEvent 函数来触发自定义事件。请注意,eventData 是事件数据的占位符,您可以根据需要替换为实际的事件数据。
- <div>
- <button @click="emitCustomEvent">触发自定义事件button>
- div>
-
- <script setup>
- import { defineEmits } from 'vue';
-
- // 使用 defineEmits 定义可触发的自定义事件
- const emits = defineEmits(['custom-event-name']);
-
- // 创建一个函数来触发自定义事件
- const emitCustomEvent = () => {
- emits('custom-event-name', eventData);
- };
- script>
我们在父组件的 部分使用 @custom-event-name(或 v-on:custom-event-name)来监听子组件触发的名为 custom-event-name 的自定义事件。然后,在 部分,我们通过定义 handleCustomEvent 函数来处理自定义事件触发的逻辑。
- <div>
- <child-component @custom-event-name="handleCustomEvent">child-component>
- div>
-
- <script setup>
- import ChildComponent from './ChildComponent.vue';
-
- // 监听子组件触发的自定义事件
- const handleCustomEvent = (eventData) => {
- // 处理自定义事件触发的逻辑
- console.log('自定义事件触发了,事件数据:', eventData);
- };
- script>
在一个单独的 Vue 实例上添加事件总线,通常在一个单独的文件中。
- // EventBus.js
-
- import Vue from 'vue';
- export const EventBus = new Vue();
在任何组件中,您可以使用 $emit 方法来触发事件。
- // 发送组件
- import { EventBus } from './EventBus.js';
-
- export default {
- methods: {
- sendData() {
- EventBus.$emit('custom-event-name', eventData);
- }
- }
- }
在任何组件中,您可以使用 $emit 方法来触发事件。
- // 发送组件
- import { EventBus } from './EventBus.js';
-
- export default {
- methods: {
- sendData() {
- EventBus.$emit('custom-event-name', eventData);
- }
- }
- }
首先安装第三方插件 mitt(也称为 Micro Event Emitter)来实现事件总线的功能,这对于在 Vue 3 中进行组件通信是一种常见的方法。mitt 是一个轻量级的事件发射器库,可以用于处理事件的触发和监听。
npm install mitt
- // EventBus.js
- import mitt from 'mitt';
-
- // 创建事件总线实例
- const emitter = mitt();
-
- export default emitter;
- // 发送组件
- <button @click="sendData">触发事件button>
-
- <script setup>
- import emitter from './EventBus.js';
-
- const sendData = () => {
- emitter.emit('custom-event-name', eventData);
- }
- script>
- // 接收组件
- <div>div>
-
- <script setup>
- import emitter from './EventBus.js';
-
- emitter.on('custom-event-name', eventData => {
- // 处理事件数据
- });
- script>
我们创建了一个名为 EventBus.js 的文件,其中包含了 mitt 的实例,这个实例被用作事件总线。然后,在发送组件和接收组件中,我们都导入了 EventBus.js 并使用它来触发和监听自定义事件。
在 Vue 2 中,provide 和 inject 是通过父组件向子孙组件传递数据的一种方式。父组件使用 provide 提供数据,然后子孙组件使用 inject 来注入这些数据。
- <div>
- <child-component>child-component>
- div>
-
- <script>
- export default {
- provide: {
- message: 'Hello from parent!'
- }
- }
- script>
- <div>
- <grandchild-component>grandchild-component>
- div>
-
- <script>
- export default {
- inject: ['message'],
- mounted() {
- console.log(this.message); // 输出:Hello from parent!
- }
- }
- script>
provide 和 inject在 Vue 3 中,provide 和 inject 的使用方式与 Vue 2 类似,但有一些改进,特别是在 TypeScript 和 Composition API 中的使用更方便。
- <div>
- <child-component>child-component>
- div>
-
- <script setup>
- import { provide } from 'vue';
- provide('message', 'Hello from parent!');
- script>
- <div>
- <grandchild-component>grandchild-component>
- div>
-
- <script setup>
- import { inject } from 'vue';
-
- const message = inject('message');
-
- // 使用注入的数据
- console.log(message); // 输出:Hello from parent!
-
- script>
Vue 3 的 Composition API 使得在 setup 函数中更容易使用 provide 和 inject。在 setup 中提供的数据会自动反应到子组件中,无需额外的设置。此外,由于 Vue 3 更好地支持 TypeScript,因此类型检查更加准确。
状态管理工具
详细查看一下博客
Pinia
http://t.csdnimg.cn/22mmUVueX
http://t.csdnimg.cn/hvOi4
Vue 中的插槽(slot)是一种用于在父组件中向子组件传递内容的机制,而不仅仅是数据通信。通过插槽,您可以将任何内容(如文本、HTML、其他组件等)传递给子组件,并在子组件中进行渲染。虽然插槽主要用于渲染内容,但您仍然可以在插槽中包含数据,并且通过插槽的方式进行通信。
- <template>
- <div>
- <child-component>
-
- <template #custom-slot>
- <p>{{ message }}p>
- <button @click="sendMessage">发送消息button>
- template>
- child-component>
- div>
- template>
-
- <script>
- import ChildComponent from './ChildComponent.vue';
-
- export default {
- components: {
- ChildComponent
- },
- data() {
- return {
- message: 'Hello from parent!'
- };
- },
- methods: {
- sendMessage() {
- this.message = 'Message sent from parent!';
- }
- }
- };
- script>
- <template>
- <div>
- <slot name="custom-slot">slot>
- div>
- template>
-
- <script>
- export default {
- // 子组件可以在这里接收插槽内容
- mounted() {
- const customSlotContent = this.$slots['custom-slot'];
-
- // 监听按钮点击事件并触发通信
- customSlotContent[1].componentInstance.$on('click', () => {
- this.$emit('custom-event', 'Message received in child!');
- });
- }
- };
- script>
父组件 ParentComponent 包含了一个名为 custom-slot 的插槽,其中包含了一个段落元素和一个按钮。父组件通过插槽向子组件 ChildComponent 传递了数据和一个触发通信的按钮。
子组件 ChildComponent 接收了插槽内容,并在其中监听按钮的点击事件。当按钮被点击时,子组件触发了一个自定义事件 custom-event,并将消息作为参数传递给父组件。