首页 > 其他分享 >[从零开始的 Vue3 系列]:Vue3 中常用组件通信全解析

[从零开始的 Vue3 系列]:Vue3 中常用组件通信全解析

时间:2024-09-30 10:49:52浏览次数:11  
标签:vue const 从零开始 sharedData Vue3 组件 import emit

前言

本系列将从零开始,系统性地介绍 Vue 3 的常用 API,逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示,帮助大家掌握 Vue 3 的基础与进阶知识,最终具备独立搭建完整 Vue 3 项目的能力。

vue3中的组件通信

Vue 3 提供了多种方式来进行组件之间的通信。根据场景的不同,开发者可以选择最合适的方式进行数据的传递与事件的处理。

1. 通过 Props 传递数据(父 -> 子)

父组件:

<template>
  <ChildComponent :message="parentMessage" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';

const parentMessage = 'Hello from Parent';
</script>

子组件:

<template>
//写法1
  <p>{{ message }}</p>
  //写法2
   <p>{{ props.message }}</p>
</template>

<script setup>
//写法1
defineProps({
  message: String
});
//写法2
const props=defineProps({
  message: String
});
</script>

2.通过 Emit 传递事件(子 -> 父)

子组件可以通过 emit 函数向父组件传递事件。不过写法和vue2有点不一样。

子组件:

<template>
  <button @click="sendMessage">Send Message</button>
</template>

<script setup>
//创建一个emit,
//defineEmits数组内包含的是传给父组件的方法,多个的话以逗号隔开,
//  例子: defineEmits(['message','xxx']);
const emit = defineEmits(['message']);

const sendMessage = () => {
//使用emit像父组件传值,message为方法名,逗号后面为传递的值
//如果是定义的值直接写入就行,这里例子使用的是一个字符串
  emit('message', 'Hello from Child');
}
</script>

父组件:

<template>
	//和vue2一样的写法
  <ChildComponent @message="handleMessage" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';

const handleMessage = (msg) => {
  console.log(msg);
}
</script>

3.兄弟组件通信 (Provide & Inject) :用的较少

通过 provide 和 inject,我们可以在兄弟组件之间实现数据共享。

在父先组件中使用 provide: 提供数据或方法。
父组件:

<template>
  <div>
    <ChildComponentA />
    <ChildComponentB />
  </div>
</template>

<script setup>
import { ref, provide } from 'vue';
import ChildComponentA from './ChildComponentA.vue';
import ChildComponentB from './ChildComponentB.vue';

const sharedData = ref('Hello from Parent');
provide('sharedData', sharedData);

function updateData(newData) {
  sharedData.value = newData;
}

provide('updateData', updateData);
</script>

</script>

子组件A:

<template>
  <div>
    <p>Data: {{ sharedData }}</p>
    <button @click="changeData">Change Data</button>
  </div>
</template>

<script setup>
import { inject } from 'vue';

const sharedData = inject('sharedData');
const updateData = inject('updateData');

function changeData() {
  updateData('Data changed by Component A');
}
</script>

子组件B:

<template>
  <div>
    <p>Data: {{ sharedData }}</p>
  </div>
</template>

<script setup>
import { inject } from 'vue';

const sharedData = inject('sharedData');
</script>

原理:

  • 父组件使用 provide 提供了一个响应式数据 sharedData 和一个方法 updateData。这些可以被子组件访问
  • 子组件A使用 inject 获取 sharedData 和 updateData,并通过按钮点击更新数据。
  • 子组件B使用 inject 获取 sharedData,当数据被兄弟组件 A 更新时,它会自动响应并更新显示。

简单的数据传递可以考虑这种方式,如果是复杂的还是选择Pinia吧,后面会有一篇专门讲解Pinia的文章,感兴趣的小伙伴可以去点评一下哦~

4.全局状态管理 (Pinia)

在复杂场景中,使用 Pinia 或 Vuex 可以更高效地进行全局状态管理。
定义 store:

import { defineStore } from 'pinia';

export const useStore = defineStore('main', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++;
    }
  }
});

在组件中使用 Pinia:

<template>
  <p>Count: {{ count }}</p>
  <button @click="increment">Increment</button>
</template>

<script setup>
import { useStore } from './store';

const store = useStore();
const { count, increment } = store;
</script>

5. ref 和父子组件的事件绑定

ref 可以用来获取子组件实例或 DOM 节点,并直接调用子组件方法。用法和vue2差不多,只是写法有一些变化

父组件:

<template>
  <ChildComponent ref="childRef" />
  <button @click="callChildMethod">Call Child Method</button>
</template>

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

const childRef = ref(null);

const callChildMethod = () => {
  childRef.value.someMethod();
}
</script>

子组件:

<script setup>
const someMethod = () => {
  console.log('Child method called');
}
</script>

6.自定义事件(通过 v-model 进行双向绑定)

自定义事件和 v-model 结合使用可以实现组件的双向绑定。这个功能允许你在父组件和子组件之间同步数据。
父组件:

<template>
  <div>
    <h1>Parent Component</h1>
    <ChildComponent v-model="parentData" />
    <p>Parent Data: {{ parentData }}</p>
  </div>
</template>

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

const parentData = ref('Initial data');
</script>


子组件:

<template>
  <div>
    <input :value="modelValue" @input="onInputChange" />
  </div>
</template>

<script setup>
import { defineEmits, defineProps } from 'vue';

// 定义接收的 props
const props = defineProps({
  modelValue: String
});

// 定义 emit 事件
const emit = defineEmits(['update:modelValue']);

const onInputChange = (event) => {
  emit('update:modelValue', event.target.value);
};
</script>

原理

  • 子组件: 子组件通过 props 接收数据,通过 emit 触发更新事件。v-model 默认使用 modelValue 和
    update:modelValue 作为 prop 和事件名称。
  • 父组件: 父组件通过 v-model 进行绑定,当子组件触发 update:modelValue 事件时,父组件的对应数据会自动更新。

自定义属性名
可以自定义 v-model 的属性名。例如,如果想用 value 和 input 代替 modelValue 和 update:modelValue:

子组件:

<template>
  <div>
    <input :value="value" @input="onInputChange" />
  </div>
</template>

<script setup>
import { defineEmits, defineProps } from 'vue';

// 定义接收的 props
const props = defineProps({
  value: String
});

// 定义 emit 事件
const emit = defineEmits(['input']);

const onInputChange = (event) => {
  emit('input', event.target.value);
};
</script>

父组件:

<template>
  <div>
    <h1>Parent Component</h1>
    <ChildComponent v-model:value="parentData" />
    <p>Parent Data: {{ parentData }}</p>
  </div>
</template>

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

const parentData = ref('Initial data');
</script>

总结

在 Vue 3 中,组件通信是构建动态、交互式应用的核心。了解并掌握不同的组件通信方式能帮助我们更高效地管理数据流动和事件处理。

  1. Props 传递数据(父 -> 子): 使用 props 在父组件向子组件传递数据是最基础的通信方式。
  2. Emit 传递事件(子 -> 父): 子组件使用 emit 向父组件传递事件,以实现事件驱动的通信。
  3. Provide & Inject(兄弟组件间通信): 通过 provide 和 inject 可以在组件树中实现数据共享,适合简单的状态共享。
  4. 全局状态管理 (Pinia): 在复杂场景中,使用 Pinia(或 Vuex)进行全局状态管理,提供了一种高效的状态共享和管理方式。
  5. ref 和父子组件的事件绑定: 使用 ref 获取子组件实例,允许父组件直接调用子组件的方法。
  6. 自定义事件和 v-model 双向绑定: 结合自定义事件与 v-model 实现数据的双向绑定,使父子组件间的数据同步更为简便。

每种通信方式都有其适用场景,选择合适的方式能够提高应用的可维护性和可扩展性。在实际开发中,根据应用需求灵活运用这些方式,能有效提升开发效率和代码质量。

ps:以上内容仅为本人对 vue3生命周期的个人理解,如有不足之处,欢迎大家指正与交流,共同进步。

标签:vue,const,从零开始,sharedData,Vue3,组件,import,emit
From: https://blog.csdn.net/llfxq/article/details/142637927

相关文章

  • DevExpress WinForms v24.1新版亮点:富文本编辑器、电子表格组件功能升级
    DevExpressWinForms拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!DevExpressWinForms控件v24.1日前已经全新发布,新......
  • vue3滚动条无法监测滚动高度问题
    第一个是根组件第二个是子组件第三个是滚动复用组件<el-scrollbarref="scroll"style="height:100%"@scroll="handleScroll">在滚动复用组件中想要监测滚动的高度变化,一开始没有使用el-scrollbar组件而是直接使用原生的格式导致如图所示滚动条与文......
  • 从零开始学机器学习——逻辑回归
    首先给大家介绍一个很好用的学习地址:https://cloudstudio.net/columns在之前的学习中,我们学习了直线线性回归与多项式回归,我们今天的主题则是逻辑回归,我记得在前面有讲解过这两个回归的区别,那么今天我们主要看下逻辑回归有哪些特征需要我们识别的。逻辑回归逻辑回归主要用于解......
  • LlamaExtract - LlamaCloud 非结构化文档提取组件
    文章目录一、关于LlamaExtract定价和使用数据定价使用数据二、快速启动使用web用户界面获取一个API密钥使用我们的library使用RESTAPI三、使用UI后续步骤四、获取API密钥五、在Python中使用六、使用RESTAPI1、上传文件2、推断并创建一个模式3、开始一项提取任务......
  • 【2024精华版】从零开始的大模型LLM学习全攻略:一文掌握从入门到精通
    ChatGPT的出现在全球掀起了AI大模型的浪潮,2023年可以被称为AI元年,AI大模型以一种野蛮的方式,闯入你我的生活之中。从问答对话到辅助编程,从图画解析到自主创作,AI所展现出来的能力,超出了多数人的预料,让不少人惊呼:“未来是属于AI的”。AI大模型——成为互联网从业者必备技能。......
  • 自然资源领域的组件报批:守护绿水青山的智慧钥匙
    在追求绿色发展的今天,自然资源的合理利用与有效保护成为了社会关注的焦点。组件报批作为自然资源开发与保护的前置门槛,如同一把精密的钥匙,解锁着可持续发展的大门。本文将带您走进自然资源领域的组件报批世界,探析其背后的逻辑、重要性以及如何在实践中更好地守护我们的绿水青山......
  • 【Ambari自定义组件集成】Ambari汉化,源码级修改手把手教程
    传统方式注意:此方法适合ambari-2.8.0注意:此方法适合ambari-2.8.0注意:此方法适合ambari-2.8.0Step1、找到代码位置:ambari-project\ambari-web\app\messages.js逐一替换Step2、下载我提供的汉化好的:message.jshttps://gitee.com/tt-bigdata/ambari-en-cn/blob/ma......
  • React周视图组件封装
    技术栈:React、antd需求背景使用周视图来显示广播信息与状态组件特点当多个广播时间段交叠时,并行显示。对于交叠广播,最多显示3个,如果要显示全部交叠的广播,可点击展开。可对时间段精度进行扩展。当多个时间短但不重叠的广播放在一起时,更方便看。支持点击回到本周。效果展......
  • vue快捷开发(组件的使用)
    可以写一个主界面的view,在左侧侧边栏加一个导航栏,通过导航栏的按钮点击来切换不同的界面,组件的使用小细节(1)在view代码中①在导航栏上面加上按钮,点击按钮实现组件的展示(此处的showContent就是在界面右侧展示出组件) ②在script中导入不同的内容组件 注意组件的导入方式......
  • Hadoop三大组件之YARN(一)
    YARN架构与任务提交流程详解1.YARN的组成架构YARN(YetAnotherResourceNegotiator)是Hadoop生态系统中的一个重要组成部分,主要用于资源管理和调度。YARN的架构主要由以下几个关键组件构成:1.1ResourceManager(RM)ResourceManager是YARN的核心组件,负责整个集群的资源管理......