vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue3组件传参

Vue3组件传参的多种方式小结

作者:五号厂房

这篇文章主要介绍 Vue3组件传参的方式,包括父子组件、跨层级组件、兄弟组件的传参,如父子组件通过属性绑定和自定义事件双向传参,跨层级组件可利用 Provide/Inject 机制和 Pinia 状态管理,兄弟组件可通过父组件中转或 mitt 库直接传参,需要的朋友可以参考下

一、Vue3 组件传参概述

在 Vue 3 的应用开发旅程中,组件间的高效通信是构建复杂交互式应用的关键基石。无论是小型项目中简单的父子组件协作,还是大型应用里多层嵌套组件、兄弟组件之间的默契配合,精准且流畅的参数传递都起着决定性作用。它确保了数据能在各个组件 “岗位” 按需流动,使得整个应用如同精密运转的机器,为用户带来流畅且一致的体验。接下来,就让我们深入探究 Vue 3 组件传参的奥秘世界。

二、父子组件传参

(一)父组件向子组件传参

父组件作为数据的源头,常常需要将某些信息精准地传递给子组件,以便子组件基于这些数据进行个性化展示或执行特定逻辑。在 Vue 3 中,这一过程通过属性绑定优雅实现。例如,父组件拥有一个关键数据parentMessage,在使用子组件标签时,像这样绑定数据:

<template>
  <ChildComponent :message="parentMessage" />
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
const parentMessage = '这是来自父组件的消息';
</script>

而子组件则利用defineProps来接收这份来自父方的 “馈赠”:

<template>
  <div>{{ message }}</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
  message: String
});
</script>

如此一来,子组件就能顺利获取父组件传递的message数据,并在模板中灵活运用。

(二)子组件向父组件传参

有时,子组件内部发生的某些变化或产生的数据,需要及时反馈给父组件知晓。这时,子组件就会扮演信息传递者的角色,通过defineEmits触发自定义事件来达成这一目的。假设子组件中有个按钮,点击后要向父组件传递一段文本数据,代码如下:

<template>
  <button @click="sendDataToParent">向父组件传数据</button>
</template>
<script setup>
import { defineEmits } from 'vue';
const emits = defineEmits(['send-data']);
const sendDataToParent = () => {
  const data = '子组件的数据';
  emits('send-data', data);
};
</script>

父组件则在使用子组件标签时,敏锐地监听这个自定义事件:

<template>
  <ChildComponent @send-data="handleChildData" />
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
const handleChildData = (data) => {
  console.log('收到子组件数据:', data);
};
</script>

这般双向的信息互通,让父子组件间的协作亲密无间。

(三)案例实操:计数器组件

为了更直观地感受父子组件传参的魅力,我们构建一个简易计数器案例。父组件负责展示计数器的当前数值,并提供操作按钮,子组件则承载计数器的增减逻辑。
父组件:

<template>
  <div>
    当前计数: <span>{{ count }}</span>
    <ChildComponent :count="count" @update-count="updateCount" />
  </div>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
import { ref } from 'vue';
const count = ref(0);
const updateCount = (newCount) => {
  count.value = newCount;
};
</script>
<template>
  <button @click="increment">增加</button>
  <button @click="decrement">减少</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
  count: Number
});
const emits = defineEmits(['update:count']);
const increment = () => {
  emits('update:count', props.count + 1);
};
const decrement = () => {
  emits('update:count', props.count - 1);
};
</script>

当点击子组件中的增减按钮,子组件通过事件将新的计数数值传递给父组件,父组件更新自身状态,实现了计数器功能的流畅运作。

三、跨层级组件传参

(一)Provide/Inject 机制

在多层嵌套的组件架构中,若按照常规的父子组件传参方式一级级传递数据,会使代码变得繁琐不堪,犹如一条冗长且错综复杂的信息传递链。此时,Vue 3 提供的 Provide/Inject 机制就如同一条 “捷径”,让祖先组件能够直接为后代组件 “空投” 所需数据。
祖先组件:

<template>
  <div>
    <MiddleComponent />
  </div>
</template>
<script setup>
import { provide } from 'vue';
import MiddleComponent from './MiddleComponent.vue';
const sharedData = '祖先共享的数据';
provide('sharedData', sharedData);
</script>

中间组件(仅作为层级过渡,不做数据处理):

<template>
  <div>
    <ChildComponent />
  </div>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
</script>

后代组件:

<template>
  <div>{{ injectedData }}</div>
</template>
<script setup>
import { inject } from 'vue';
const injectedData = inject('sharedData');
</script>

通过provide在祖先组件声明共享数据,后代组件利用inject轻松获取,大大简化了跨层级数据传递的复杂度。

(二)Pinia 状态管理

Pinia 作为 Vue 3 生态中备受瞩目的状态管理库,为跨层级组件数据共享提供了一套强大且优雅的解决方案。相较于传统的 Vuex,它具有更简洁的 API 和更直观的使用方式。
首先,创建一个 Pinia store 实例:

import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    }
  }
});

在组件中使用时,无论是哪个层级的组件,只要引入并调用相应方法,就能实现数据的共享与操作:
父组件:

<template>
  <div>
    当前计数: <span>{{ counterStore.count }}</span>
    <ChildComponent />
  </div>
</template>
<script setup>
import { useCounterStore } from './store';
const counterStore = useCounterStore();
</script>

子组件:

<template>
  <button @click="increment">增加</button>
  <button @click="decrement">减少</button>
</template>
<script setup>
import { useCounterStore } from './store';
const counterStore = useCounterStore();
const increment = () => {
  counterStore.increment();
};
const decrement = () => {
  counterStore.decrement();
};
</script>

通过 Pinia,组件们仿佛连接到了一个共享的数据中枢,轻松实现跨层级的无缝协作。

四、兄弟组件传参

(一)通过父组件中转

当兄弟组件需要交流信息时,由于它们在层级上平起平坐,无法直接传递数据,这时父组件就可以充当一个可靠的 “中间人”。例如,有两个兄弟组件,一个是输入框组件用于输入文本,另一个是显示组件用于展示输入框中的内容。
父组件:

<template>
  <InputComponent @input-text="handleInputText" />
  <DisplayComponent :display-text="displayText" />
</template>
<script setup>
import InputComponent from './InputComponent.vue';
import DisplayComponent from './DisplayComponent.vue';
import { ref } from 'vue';
const displayText = ref('');
const handleInputText = (text) => {
  displayText.value = text;
};
</script>

输入框组件:

<template>
  <input type="text" @input="sendText" />
</template>
<script setup>
import { defineEmits } from 'vue';
const emits = defineEmits(['input-text']);
const sendText = (e) => {
  emits('input-text', e.target.value);
};
</script>

显示组件:

<template>
  <div>{{ displayText }}</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
  displayText: String
});
</script>

输入框组件将输入的文本通过父组件中转传递给显示组件,实现了兄弟组件间的间接通信。

(二)使用 mitt 库直接传参

除了借助父组件中转,还可以利用 mitt 库实现兄弟组件间更为直接的参数传递。mitt 库提供了一个轻量级的事件总线功能。
首先安装并引入 mitt 库:

npm install mitt
import mitt from 'mitt';
const emitter = mitt();

在发送数据的组件中:

<template>
  <button @click="sendData">向兄弟组件传数据</button>
</template>
<script setup>
import { ref } from 'vue';
const data = ref('兄弟组件的数据');
const sendData = () => {
  emitter.emit('data-transfer', data.value);
};
</script>

在接收数据的组件中:

<template>
  <div>{{ receivedData }}</div>
</template>
<script setup>
import { onMounted } from 'vue';
import mitt from './mitt';
const receivedData = ref('');
onMounted(() => {
  mitt.on('data-transfer', (data) => {
    receivedData.value = data;
  });
});
</script>

借助 mitt 库创建的事件总线,兄弟组件可以跳过父组件,直接建立高效的数据传输通道。

五、组件传参的注意事项

(一)单向数据流原则

在 Vue 3 组件传参体系中,单向数据流是一条神圣不可侵犯的规则。父组件传递给子组件的数据,子组件应视作只读的 “圣经”,绝不能随意篡改。若子组件需要基于父组件数据进行变更,务必通过触发事件告知父组件,由父组件来完成数据的更新操作。这就如同一个严谨的指挥链条,确保数据流向的可预测性,避免因随意修改数据引发难以排查的错误,让整个应用始终处于稳定可控的状态。

(二)属性命名规则

组件间传递参数时,属性命名犹如给数据贴上的标签,需格外谨慎。在父组件的组件标签上绑定属性时,要遵循合法的 HTML 属性命名规范,避免使用特殊字符或保留字。子组件接收属性时,命名应与父组件传递时保持严格一致,否则就会出现数据 “迷路” 的情况,导致组件无法正确获取所需信息,影响应用的正常运行。

六、总结与展望

回顾 Vue 3 组件传参的多种精妙方式,从父子组件的亲密互动,到跨层级组件的高效协作,再到兄弟组件的灵活通信,每一种方式都针对特定场景发挥着独特优势。这些传参技巧如同搭建 Vue 3 应用大厦的坚固榫卯,紧密连接各个组件模块,让应用得以稳固构建并流畅运行。

以上就是Vue3组件传参的多种方式小结的详细内容,更多关于Vue3组件传参的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文