Vue3组件通信方法清单

发布于:2025-07-27 ⋅ 阅读:(11) ⋅ 点赞:(0)

1. Props / Emits(父子通信)​

​适用场景​

父组件传递数据给子组件,子组件通知父组件。

​代码示例​

<!-- 父组件 -->
<template>
  <ChildComponent 
    :message="parentMsg" 
    @update="handleUpdate"
  />
</template>

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

const parentMsg = ref('Hello from Parent');
const handleUpdate = (newMsg) => {
  parentMsg.value = newMsg;
};
</script>

<!-- 子组件 Child.vue -->
<template>
  <button @click="$emit('update', 'New message')">
    点击更新: {{ message }}
  </button>
</template>

<script setup>
defineProps(['message']);
defineEmits(['update']);
</script>

2. v-model(双向绑定)​

​适用场景​

简化父子组件的双向数据绑定。

​代码示例

<!-- 父组件 -->
<template>
  <CustomInput v-model="inputValue" />
</template>

<script setup>
import { ref } from 'vue';
const inputValue = ref('');
</script>

<!-- 子组件 CustomInput.vue -->
<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>

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

3. provide / inject(跨层级通信)​

​适用场景​

祖先组件向后代组件传递数据,避免逐层传递 props。

​代码示例​

<!-- 祖先组件 -->
<template>
  <MiddleComponent />
</template>

<script setup>
import { provide, ref } from 'vue';
const theme = ref('dark');
provide('theme', theme); // 提供数据
</script>

<!-- 后代组件(任意层级) -->
<script setup>
import { inject } from 'vue';
const theme = inject('theme'); // 注入数据
</script>

4. 事件总线(任意组件通信)​

​适用场景​

非父子组件间的通信,如兄弟组件或跨多层级组件。

​代码示例(使用 mitt)

// 创建事件总线(utils/eventBus.js)
import mitt from 'mitt';
export const emitter = mitt();

// 组件A(发送事件)
import { emitter } from './eventBus';
emitter.emit('message', 'Hello from A');

// 组件B(接收事件)
import { emitter } from './eventBus';
emitter.on('message', (msg) => {
  console.log(msg); // "Hello from A"
});

5. ref / 模板引用​

​适用场景​

父组件直接调用子组件的方法或访问其数据。

​代码示例​

<!-- 父组件 -->
<template>
  <ChildComponent ref="childRef" />
  <button @click="callChildMethod">调用子组件方法</button>
</template>

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

const callChildMethod = () => {
  childRef.value.sayHello(); // 直接调用子组件方法
};
</script>

<!-- 子组件 -->
<script setup>
const sayHello = () => {
  console.log('Hello from Child!');
};
// 暴露方法给父组件
defineExpose({ sayHello });
</script>

6. Pinia(全局状态管理)​

​适用场景​

多个组件共享复杂状态(如用户登录信息)。

​代码示例​

// 定义 store
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
  state: () => ({ name: 'Alice' }),
  actions: {
    updateName(newName) {
      this.name = newName;
    }
  }
});

// 组件中使用
import { useUserStore } from '@/store/user';
const userStore = useUserStore();
console.log(userStore.name); // "Alice"
userStore.updateName('Bob'); // 调用 action

7. 插槽(Slot)通信​

​适用场景​

父组件向子组件传递模板片段。

​代码示例

<!-- 子组件 -->
<template>
  <div class="card">
    <slot name="header" :user="user"></slot>
    <slot></slot>
  </div>
</template>

<script setup>
const user = { name: 'Alice' };
</script>

<!-- 父组件 -->
<template>
  <ChildComponent>
    <template #header="{ user }">
      <h1>{{ user.name }}的头像</h1>
    </template>
    <p>这是默认插槽内容</p>
  </ChildComponent>
</template>

8. Local Storage / Cookies​

​适用场景​

持久化存储数据,跨页面共享。

注意,只有同源的页面才能共享localstorage的数据

​代码示例​

// 存储数据
localStorage.setItem('theme', 'dark');

// 读取数据(任何组件中均可)
const theme = localStorage.getItem('theme');

总结:如何选择?​

方法

适用场景

优点

​Props/Emits​

父子组件简单通信

直观、Vue 官方推荐

​v-model​

表单双向绑定

语法糖简化代码

​provide/inject​

跨层级组件通信

避免 prop 逐层传递

​事件总线​

任意组件间通信

解耦、灵活

​ref​

父组件调用子组件方法

直接访问子组件实例

​Pinia​

复杂全局状态管理

类型安全、DevTools 支持

​插槽​

父组件定制子组件 UI

高度灵活的模板组合

​本地存储​

持久化数据(如用户偏好)

页面刷新后数据不丢失


网站公告

今日签到

点亮在社区的每一天
去签到