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 适用于多组件共享状态,功能强大但也引入了复杂度。

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

相关推荐
m0_748244964 分钟前
【AI系统】LLVM 前端和优化层
前端·状态模式
明弟有理想4 分钟前
Chrome RCE 漏洞复现
前端·chrome·漏洞·复现
平行线也会相交5 分钟前
云图库平台(二)前端项目初始化
前端·vue.js·云图库平台
shimmer0086 分钟前
抖音小程序登录(前端通过tt.login获取code换取openId)
前端·小程序·状态模式
嘤嘤怪呆呆狗16 分钟前
【开发问题记录】使用 Docker+Jenkins+Jenkins + gitee 实现自动化部署前端项目 CI/CD(centos7为例)
前端·vue.js·ci/cd·docker·gitee·自动化·jenkins
鱼钓猫的小鱼干21 分钟前
table 表格转成 excell 导出
前端·vue·excel
一只搬砖的猹23 分钟前
cJson系列——常用cJson库函数
linux·前端·javascript·python·物联网·mysql·json
CodeClimb35 分钟前
【华为OD-E卷-租车骑绿道 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
懒羊羊我小弟42 分钟前
包管理工具npm、yarn、pnpm、cnpm详解
前端·npm·node.js·yarn·cnpm
ppo_wu1 小时前
更改 pnpm 的全局存储位置
前端·vue