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. <math xmlns="http://www.w3.org/1998/Math/MathML"> 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. </math>emit、eventBus.config.globalProperties.on;3、用状态库 vuex或者 pinia
多级:1、provide/inject 多级传;2、用状态库 vuex或者 pinia;3、用库 mitt。
只看现在莫回头