Vue3 组件间通信

Vue3 中组件之间传值的方式有多种,下面我将通过示例代码介绍几种常见的传值方式。

1. 父组件向子组件传值(Props)

父组件可以通过 props 向子组件传递数据。子组件通过 props 选项接收数据,然后在模板中使用。这种方式适用于父组件向子组件单向传递数据的场景。

关键代码

父组件:

html 复制代码
<child-component :parent-message="messageToChild"></child-component>

子组件:

js 复制代码
export default {
  props: {
    parentMessage: String
  }
}

2. 子组件向父组件传值(自定义事件)

子组件可以通过 $emit 触发自定义事件,将数据传递给父组件。父组件通过 v-on 监听子组件触发的事件,接收数据。这种方式适用于子组件需要向父组件传递数据或通知父组件事件的场景。

关键代码

子组件:

js 复制代码
methods: {
  sendMessage() {
    this.$emit('child-message', 'Hello from child!')
  }
}

父组件:

html 复制代码
<child-component @child-message="receiveMessage"></child-component>

3. 使用 $attrs 透传属性

$attrs 是 Vue 组件的一个内置属性,它包含了父组件传递给子组件的属性(除了 props 定义的属性和 class、style 之外)。通过 $attrs,可以将这些属性直接传递给子组件的根元素或其他子元素。

关键代码

父组件:

html 复制代码
<child-component parentmessage="messageToChild" @input="onChildInput"></child-component>

子组件:

html 复制代码
<template>
  <div class="child">
    <h3>Child Component</h3>
    <p>Message from parent: {{ $attrs.parentmessage }}</p>
    <input type="text" v-bind="$attrs" />
  </div>
</template>

<script>
export default {
  inheritAttrs: false, // 禁用默认的属性继承行为
  // ...
}
</script>

在父组件中,我们给 <child-component> 传递了一个名为 parentmessage 的属性。

在子组件中,通过 $attrs.parentmessage 可以访问到这个属性的值。同时,通过 v-bind="$attrs",将 $attrs 中的所有属性绑定到 <input> 元素上。

注意,如果要在子组件的根元素上使用 $attrs,需要设置 inheritAttrs: false,以禁用默认的属性继承行为。

使用 $attrs 可以方便地透传属性,减少重复的 props 定义,使组件更加灵活和可复用。

4. 兄弟组件之间传值(事件总线 EventBus)

对于没有直接父子关系的组件,可以使用事件总线 EventBus 来传递数据。通过一个外部的事件总线,用 $emit 触发事件,用 $on 监听事件。这种方式适用于兄弟组件之间需要通信的场景,但在大型应用中可能会变得难以维护。

关键代码

js 复制代码
// event-bus.js
import mitt from 'mitt'
const eventBus = mitt()
export default eventBus

组件 A:

js 复制代码
import eventBus from '@/event-bus'
eventBus.emit('message', 'Hello from A!')

组件 B:

js 复制代码
import eventBus from '@/event-bus'
eventBus.on('message', (data) => {
  console.log(data) // Hello from A!
})

5. 父组件通过 refs 访问子组件

父组件可以通过 ref 属性给子组件设置一个引用名称,然后通过 $refs 访问子组件的实例,从而调用子组件的方法或访问子组件的数据。这种方式适用于父组件需要直接访问子组件的场景,但应该谨慎使用,因为它增加了组件之间的耦合度。

关键代码

父组件:

html 复制代码
<child-component ref="childRef"></child-component>
js 复制代码
mounted() {
  this.$refs.childRef.someMethod()
}

6. 通过 provide / inject 传值

父组件通过 provide 提供数据,子组件通过 inject 获取数据。这种方式适用于深度嵌套的组件,可以跨越多个层级直接传递数据。在 Vue3 中,我们可以使用 provideinject 来实现响应式数据的传递。

关键代码

父组件:

js 复制代码
import { provide, ref } from 'vue'

setup() {
  const count = ref(0)

  const incrementCount = () => {
    count.value++
  }

  provide('count', count)
  provide('incrementCount', incrementCount)

  return {
    count,
    incrementCount
  }
}

子组件:

js 复制代码
import { inject } from 'vue'

setup() {
  const count = inject('count')
  const incrementCount = inject('incrementCount')

  return {
    count,
    incrementCount
  }
}

在父组件中,通过 provide 提供了一个响应式的 count 数据和一个 incrementCount 方法。子组件通过 inject 获取了这些数据和方法,并在模板中使用。当在父组件或子组件中修改 count 的值时,另一个组件中的 count 也会同步更新,实现了响应式数据的传递。

7. Vuex 状态管理

对于大型应用,可以使用 Vuex 进行状态管理。将共享的数据存储在 Vuex 的 store 中,任何组件都可以通过 dispatch 提交 mutation 来修改状态,通过 commit 触发 action 来异步修改状态,通过 mapStatemapGetters 等辅助函数来获取状态。Vuex 适用于多个组件需要共享状态的复杂场景,但也会引入一定的复杂度。

以上就是 Vue3 中几种常见的组件间传值方式。每种方式都有其适用的场景和优缺点:

  • Props 适用于父子组件单向传值,简单直接但只能单向传递。
  • 自定义事件适用于子到父的传值,灵活方便但需要注意命名冲突。
  • $attrs 适用于透传属性,减少重复的 props 定义,使组件更加灵活和可复用。
  • 事件总线适用于兄弟组件通信,但在大型应用中可能难以维护。
  • Refs 适用于父组件直接访问子组件,但增加了耦合度。
  • Provide/inject 适用于跨层级传值,可以实现响应式数据传递。
  • Vuex 适用于多组件共享状态,功能强大但也引入了复杂度。

在实际开发中,可以根据具体需求和组件结构,灵活选择合适的传值方式,以实现组件之间清晰高效的数据共享和通信。

相关推荐
世俗ˊ20 分钟前
CSS入门笔记
前端·css·笔记
子非鱼92121 分钟前
【前端】ES6:Set与Map
前端·javascript·es6
6230_25 分钟前
git使用“保姆级”教程1——简介及配置项设置
前端·git·学习·html·web3·学习方法·改行学it
想退休的搬砖人34 分钟前
vue选项式写法项目案例(购物车)
前端·javascript·vue.js
加勒比海涛1 小时前
HTML 揭秘:HTML 编码快速入门
前端·html
啥子花道1 小时前
Vue3.4 中 v-model 双向数据绑定新玩法详解
前端·javascript·vue.js
麒麟而非淇淋1 小时前
AJAX 入门 day3
前端·javascript·ajax
茶茶只知道学习1 小时前
通过鼠标移动来调整两个盒子的宽度(响应式)
前端·javascript·css
清汤饺子1 小时前
实践指南之网页转PDF
前端·javascript·react.js
蒟蒻的贤1 小时前
Web APIs 第二天
开发语言·前端·javascript