当前位置: 首页 > news >正文

vue3除了pinia/vuex的其他通讯方式还有那些

1. Props 和 Events
Props:父组件通过 props 向子组件传递数据。
Events:子组件通过 $emit 向父组件发送事件。

<!-- ParentComponent.vue -->
<template>
  <ChildComponent :message="parentMessage" @update-message="updateMessage" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const parentMessage = ref('Hello from parent');

function updateMessage(newMessage: string) {
  parentMessage.value = newMessage;
}
</script>

<!-- ChildComponent.vue -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="sendMessage">Send Message</button>
  </div>
</template>

<script setup lang="ts">
const props = defineProps<{
  message: string;
}>();

const emit = defineEmits<{
  (e: 'update-message', message: string): void;
}>();

function sendMessage() {
  emit('update-message', 'Hello from child');
}
</script>

2. Provide / Inject
Provide:祖先组件通过 provide 提供数据。
Inject:后代组件通过 inject 获取数据。

<!-- AncestorComponent.vue -->
<template>
  <DescendantComponent />
</template>

<script setup lang="ts">
import { provide, ref } from 'vue';
import DescendantComponent from './DescendantComponent.vue';

const message = ref('Hello from ancestor');
provide('message', message);
</script>

<!-- DescendantComponent.vue -->
<template>
  <div>
    <p>{{ injectedMessage }}</p>
  </div>
</template>

<script setup lang="ts">
import { inject } from 'vue';

const injectedMessage = inject('message');
</script>

3. Event Bus
使用一个全局的 Vue 实例作为事件总线,组件可以通过它来发布和订阅事件。

// eventBus.ts
import { createApp } from 'vue';

export const eventBus = createApp({});

// ComponentA.vue
<script setup lang="ts">
import { eventBus } from './eventBus';

function sendMessage() {
  eventBus.config.globalProperties.$emit('message', 'Hello from Component A');
}
</script>

// ComponentB.vue
<script setup lang="ts">
import { onMounted } from 'vue';
import { eventBus } from './eventBus';

onMounted(() => {
  eventBus.config.globalProperties.$on('message', (message: string) => {
    console.log(message);
  });
});
</script>

4. Reactive State
使用 Vue 的 reactive 或 ref 创建一个全局状态对象,组件之间共享这个状态。

// sharedState.ts
import { reactive } from 'vue';

export const state = reactive({
  message: 'Hello from shared state',
});

// ComponentA.vue
<script setup lang="ts">
import { state } from './sharedState';

function updateMessage() {
  state.message = 'Updated message from Component A';
}
</script>

// ComponentB.vue
<template>
  <div>
    <p>{{ state.message }}</p>
  </div>
</template>

<script setup lang="ts">
import { state } from './sharedState';
</script>

5. Composables
使用 Vue 3 的 Composition API 创建可重用的逻辑,组件之间共享状态和逻辑。

// useSharedState.ts
import { ref } from 'vue';

export function useSharedState() {
  const message = ref('Hello from composable');

  function updateMessage(newMessage: string) {
    message.value = newMessage;
  }

  return { message, updateMessage };
}

// ComponentA.vue
<script setup lang="ts">
import { useSharedState } from './useSharedState';

const { message, updateMessage } = useSharedState();

function changeMessage() {
  updateMessage('Updated message from Component A');
}
</script>

// ComponentB.vue
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script setup lang="ts">
import { useSharedState } from './useSharedState';

const { message } = useSharedState();
</script>

6. Teleport
使用 Teleport 将组件渲染到 DOM 中的其他位置,适用于模态框、通知等场景。

<!-- ParentComponent.vue -->
<template>
  <div>
    <button @click="showModal = true">Show Modal</button>
    <Teleport to="body">
      <ModalComponent v-if="showModal" @close="showModal = false" />
    </Teleport>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import ModalComponent from './ModalComponent.vue';

const showModal = ref(false);
</script>

<!-- ModalComponent.vue -->
<template>
  <div class="modal">
    <p>This is a modal</p>
    <button @click="$emit('close')">Close</button>
  </div>
</template>

<script setup lang="ts">
defineEmits(['close']);
</script>

7. Custom Directives
使用自定义指令在组件之间传递数据或执行操作。

// v-my-directive.ts
import { DirectiveBinding } from 'vue';

export const myDirective = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    el.addEventListener('click', () => {
      console.log('Directive triggered with value:', binding.value);
    });
  },
};

// ComponentA.vue
<template>
  <button v-my-directive="'Hello from directive'">Click me</button>
</template>

<script setup lang="ts">
import { myDirective } from './v-my-directive';
</script>

8. Global Properties
使用 app.config.globalProperties 添加全局属性或方法,所有组件都可以访问。

// main.ts
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);

app.config.globalProperties.$myGlobalFunction = () => {
  console.log('Hello from global function');
};

app.mount('#app');

// ComponentA.vue
<script setup lang="ts">
import { getCurrentInstance } from 'vue';

const instance = getCurrentInstance();
instance?.proxy?.$myGlobalFunction();
</script>

9. Custom Events with mitt
使用第三方库 mitt 来实现轻量级的事件总线。

npm install mitt
// eventBus.ts
import mitt from 'mitt';

export const eventBus = mitt();

// ComponentA.vue
<script setup lang="ts">
import { eventBus } from './eventBus';

function sendMessage() {
  eventBus.emit('message', 'Hello from Component A');
}
</script>

// ComponentB.vue
<script setup lang="ts">
import { onMounted } from 'vue';
import { eventBus } from './eventBus';

onMounted(() => {
  eventBus.on('message', (message: string) => {
    console.log(message);
  });
});
</script>

10. Context API
使用 Vue 3 的 provide 和 inject 来实现类似 React Context 的功能。

// context.ts
import { provide, inject, ref } from 'vue';

const MessageSymbol = Symbol();

export function provideMessage() {
  const message = ref('Hello from context');
  provide(MessageSymbol, message);
}

export function useMessage() {
  const message = inject(MessageSymbol);
  if (!message) {
    throw new Error('Message not provided');
  }
  return message;
}

// ParentComponent.vue
<script setup lang="ts">
import { provideMessage } from './context';
import ChildComponent from './ChildComponent.vue';

provideMessage();
</script>

<template>
  <ChildComponent />
</template>

// ChildComponent.vue
<script setup lang="ts">
import { useMessage } from './context';

const message = useMessage();
</script>

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

相关文章:

  • AWVS(web)扫描器安装与使用
  • 记一次项目上vCenter集群恢复过程
  • 网络应用层之HTTPS
  • kubernetes-完美下载
  • java进阶1——JVM
  • 从0开始的操作系统手搓教程14——进一步完成中断子系统
  • 网络原理---HTTP/HTTPS
  • 在 MySQL 的 InnoDB 存储引擎中,部分数据库优化策略
  • 当AI搜索撕开传统搜索的裂缝,警惕AI搜索的“信息茧房”
  • LINUX、WIN32、MACOSX多个平台上GCC、MSVC之间结构体按序列大小1字节对齐
  • 《Elasticsearch实战:从零开始构建高效全文搜索引擎》
  • Webpack打包过程中如何处理ES6模块的循环依赖?
  • 基于SpringBoot的“古城景区管理系统”的设计与实现(源码+数据库+文档+PPT)
  • 力扣(leetcode)每日一题 1656 设计有序流
  • 2025 年 Java 面试高频手写代码题(附核心实现)
  • 本地部署deepseek大模型后使用c# winform调用(可离线)
  • 某查”平台请求头反爬技术解析与应对
  • css selector
  • docker部署go简单web项目(无mysql等附加功能)
  • Ubuntu从零创建Hadoop集群
  • 做网站的财务需求/seo推广系统排名榜
  • 杭州知名设计公司/seo关键词优化经验技巧
  • 手机微信网站开发/南京网站seo
  • 淮阳住房城乡建设局网站/广西seo
  • 问佛教网站大师做早课烧香烛可以吗/公司产品推广文案
  • 外贸网站怎样做推广/今日国际新闻事件