Vue3 组件通信方式全解析

vue3通信方式:父子、同级、多级。

父子

父传子

父向子传数据:

html 复制代码
<!-- 父组件 -->
<template>
  <ChildComponent :message="parentMessage" />
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const parentMessage = ref('Hello from parent')
</script>
html 复制代码
<!-- 子组件 ChildComponent.vue -->
<template>
  <div>{{ message }}</div>
</template>

<script setup>
defineProps({
  message: String
})
</script>

子传父

子组件通过 $emit 触发事件向父组件传递数据:

html 复制代码
<!-- 子组件 -->
<template>
  <button @click="sendMessage">Send to Parent</button>
</template>

<script setup>
const emit = defineEmits(['messageSent'])

function sendMessage() {
  emit('messageSent', 'Hello from child')
}
</script>
html 复制代码
<!-- 父组件 -->
<template>
  <ChildComponent @message-sent="handleMessage" />
</template>

<script setup>
function handleMessage(msg) {
  console.log(msg) // "Hello from child"
}
</script>

父子双向 v-model

html 复制代码
<!-- 父组件 -->
<template>
  <ChildComponent v-model="message" />
</template>

<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
html 复制代码
<!-- 子组件 -->
<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
</template>

<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

同级

通过同一个爸来传

html 复制代码
<!-- 父组件 -->
<template>
  <ComponentA @event="handleEvent" />
  <ComponentB :data="sharedData" />
</template>

<script setup>
import { ref } from 'vue'
const sharedData = ref(null)

function handleEvent(data) {
  sharedData.value = data
}
</script>

全局事件 event bus

html 复制代码
// eventBus.js
import { createApp } from 'vue'
export const eventBus = createApp({})

// 组件A (发送事件)
import { eventBus } from './eventBus'
eventBus.config.globalProperties.$emit('event-name', data)

// 组件B (接收事件)
import { eventBus } from './eventBus'
eventBus.config.globalProperties.$on('event-name', (data) => {
  // 处理数据
})

vuex / pinia 状态管理库

这个比较适合用复杂的组件通信:

html 复制代码
// 使用Pinia示例
// store/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() {
      this.count++
    }
  }
})
html 复制代码
// 在任何组件中使用
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
counter.increment()

多级

provide/inject

深层嵌套组件:

html 复制代码
<!-- 祖先组件 -->
<script setup>
import { provide, ref } from 'vue'

const theme = ref('dark')
provide('theme', theme)
</script>
html 复制代码
<!-- 任意后代组件 -->
<script setup>
import { inject } from 'vue'

const theme = inject('theme')
</script>

vuex / pinia 状态管理库

html 复制代码
// 使用Pinia
// store/user.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({ name: '', age: 0 }),
  getters: {
    isAdult: (state) => state.age >= 18
  },
  actions: {
    updateName(newName) {
      this.name = newName
    }
  }
})
html 复制代码
// 在任何层级的组件中
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
userStore.updateName('John')

mitt 库

html 复制代码
// eventBus.js
import mitt from 'mitt'
export const emitter = mitt()
html 复制代码
// 组件A (发送)
import { emitter } from './eventBus'
emitter.emit('event', data)
html 复制代码
// 组件B (接收)
import { emitter } from './eventBus'
emitter.on('event', (data) => {
  // 处理数据
})

总结

vue3通信方式:

父子:1、prop 父传子 defineProps;2、 defineEmits 子传父;3、父子 双向 v-model ---> defineProps('modelValue') | defineEmits('update:modelValue')

同级:1、通过一个爸;2、用event bus:eventBus.config.globalProperties. e m i t 、 e v e n t B u s . c o n f i g . g l o b a l P r o p e r t i e s . emit、eventBus.config.globalProperties. emit、eventBus.config.globalProperties.on;3、用状态库 vuex或者 pinia

多级:1、provide/inject 多级传;2、用状态库 vuex或者 pinia;3、用库 mitt。

只看现在莫回头

相关推荐
福兮说9 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理10 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆66610 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)10 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan11 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_12 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒12 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技12 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
yivifu13 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
默_笙13 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript