⚡Vue 通信 8 招:父子、跨层、全局、跨应用全场景

72 阅读1分钟

propsPinia,从 父-子跨层级,全部给出最小可运行示例,复制即用。


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️⃣ parent/parent / 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️⃣ attrs/attrs / 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,选最短路径即可。