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

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

相关推荐
dy17173 小时前
element-plus表格默认展开有子的数据
前端·javascript·vue.js
2501_915918416 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
程序员的世界你不懂7 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技7 小时前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
在未来等你7 小时前
Kafka面试精讲 Day 13:故障检测与自动恢复
大数据·分布式·面试·kafka·消息队列
gnip7 小时前
JavaScript二叉树相关概念
前端
一朵梨花压海棠go8 小时前
html+js实现表格本地筛选
开发语言·javascript·html·ecmascript
attitude.x8 小时前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java8 小时前
CSS3核心技术
前端·css·css3
空山新雨(大队长)8 小时前
HTML第八课:HTML4和HTML5的区别
前端·html·html5