从 props 到 Pinia,从 父-子 到 跨层级,全部给出最小可运行示例,复制即用。
1️⃣ props / $emit(父子通信)
<!-- Parent.vue -->
<Child :msg="msg" @update="msg=$event" />
<!-- Child.vue -->
<script setup>
defineProps(['msg'])
defineEmits(['update'])
</script>
2️⃣ v-model(双向绑定)
<!-- Parent.vue -->
<Child v-model:title="title" />
<!-- Child.vue -->
<script setup>
const title = defineModel('title')
</script>
3️⃣ refs(直接调用)
<!-- Parent.vue -->
<Child ref="child" />
<script setup>
const child = ref(null);
child.value.sayHi()
</script>
<!-- Child.vue -->
<script setup>
const sayHi = () => console.log('hi')
defineExpose({ sayHi })
</script>
4️⃣ provide / inject(跨层级)
// root.vue
provide('theme', 'dark')
// deepChild.vue
const theme = inject('theme')
5️⃣ EventBus(任意通信)
// bus.js
export const bus = mitt()
// A.vue
bus.emit('hello', 'A')
// B.vue
bus.on('hello', console.log)
6️⃣ Vuex / Pinia(全局状态)
// pinia store
export const useCounter = defineStore('counter', () => {
const count = ref(0)
const inc = () => count.value++
return { count, inc }
})
// 任意组件
const store = useCounter()
store.inc()
7️⃣ listeners(透传)
<!-- GrandChild.vue -->
<input v-bind="$attrs" @input="$emit('update:value', $event.target.value)" />
8️⃣ globalProperties(全局方法)
// main.js
app.config.globalProperties.$log = console.log
// 任意组件
this.$log('hi') // Vue2
Vue3 使用 getCurrentInstance().appContext.config.globalProperties
9️⃣ Slot 作用域(内容分发)
<!-- Parent -->
<Child>
<template #default="{ msg }">{{ msg }}</template>
</Child>
<!-- Child -->
<slot :msg="msg" />
🔟 跨框架 / 微前端(iframe / postMessage)
// 父窗口
iframe.contentWindow.postMessage({ type: 'theme', value: 'dark' }, '*')
// 子应用
window.addEventListener('message', e => console.log(e.data))
一句话总结
父子用 props/v-model,跨层 provide/inject,全局 Pinia,任意 EventBus,跨应用 postMessage,选最短路径即可。