【Vue3基础】Vue3 组件间通信

Vue3组件间通信的多种方式(超全) 通过vue和only-allow库的研究,使用一些工具和手段来约束团队,从而实现项目包管理器的规范化而这些使用这些工具,能够帮助我们更加便捷的实现规范化流程,使得项目流程上更加统一和工程化。为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。 阅读详情

Vue3中组件通信

1.方式1:defineProps

defineProps通常用于在单文件组件中,父组件向子组件传递数据。

1.1 示例

父组件 blog.vue

// Blog.vue
<template>
	<Aritice :title="AriticeItem.title" :info="AriticeItem.info" :author="AriticeItem.author">
	 <!-- 使用v-bind ( : ) ,父组件将值绑定到子组件上 -->
    </Aritice>
</template>
<script setup>
	import { reactive } from 'vue';
	import Article from '@/components/Article.vue';
	const AriticeItem = reactive({
		title: '文章标题',
	    info: '文章内容',
	    author: 'X',
	  });
</script>

子组件 Article.vue

//Article.vue
<template>
	<section>
  		<p>{{ title }}</p>
    	<p>{{ info }}</p>
    	<p>{{ author }}</p>
	</section>
</template>
<script setup>
	const props = defineProps({
		title: String,
		info: String,
		author: String,
	});
    // 对象形式声明 props
	// 等价于以字符串数组声明 props
	//const props = defineProps(['title', 'info', 'author']);
    ...
	// 在setup中使用时则直接 props.title 即可。
    const title1 = props.title;
</script>
<style></style>
1.2 补充说明

首先是关于声明方式:

以对象形式声明时,key为对应的props名称,而value则可以有多种写法。在上面的例子中,value的值为该props对应的数据类型。

const props = defineProps({
	title: String,
	...
})

而实际上,value还可以为一个对象,其中对props的相关信息进行了设定,包括:

  • type — props的类型,如果可能存在多个类型,则可以写成数组形式,例如:[String,Number]
  • default — 该props的默认值
  • require — 是否为必传项,默认为false。

以上面的title为例,其实际上可以写成:

const props = defineProps({
	title: {
        type: String,
        default: '111',
        require: false,
    }
})

以字符串数组形式声明时,数组的每一项字面量就为prop对应的名称。

const props = defineProps(['title', 'info', 'author']);

其次,关于props的使用:

在 template 模版中,直接使用defineProps()中声明的名称。

在 setup 中,只需要直接props.xxx就可以获取到该props对应的值。

另外,还需要注意:

  1. props一般是单向的,所以在子组件中不应该对 props 进行修改。如果需要在子组件中对props进行处理,应当使用ref对props进行处理后,再进行修改。

    const formatTitle = ref(props.title)
    //这样,子组件中后续对 formatTitle 的修改,就与原props.title 无关联了
    
  2. 当父组件传递的为一个对象时,例如对于上面的例子:

    <Aritice v-bind="AriticeItem"></Aritice>
    <!-- 也可 <Aritice :="AriticeItem"></Aritice>-->
    

    此时,子组件中的声明不需要改变,但是需要将该对象中将会用到的属性值通过defineProps声明出来。

  3. 在向子组件传递数据时,注意组件上用v-bind绑定的值不要重复,也不要与组件本身的属性重名!

2.defineEmits

同样地,defineEmits也常用于单文件组件的组件间通信,但其多用于子组件向父组件传递数据。

2.1 示例

父组件

<template>
  <section class="parent">
    <childVue :num="nums" @increase="handleIncrease"></childVue>
  </section>
</template>

<script setup>
  import childVue from './child.vue';
  import { ref } from 'vue';
  const nums = ref(0);
  const handleIncrease = () => {
    nums.value++;
  };
</script>

子组件

<template>
  <section class="box" @click="handelClick">{{ num }}</section>
</template>

<script setup>
  const emits = defineEmits(['increase']);
  const handelClick = () => {
    emits('increase');
  };
</script>

其效果实际上就是点击后,子组件中的value加一。

下面对该示例进行说明。

首先,在父组件中,向子组件传递了一个num的props用于展示数据。

同时,在父组件中定义了一个名为 increase 的监听事件以及事件触发后的处理函数(即把num加一)。

而在子组件中,添加了一个点击事件,在该事件的处理函数中,通过对象emit触发了父组件的 increase 监听事件,导致num加一。

2.2 具体用法

defineEmits和defineProps一样,不需要引入,可以在 setup 函数中直接使用。

defineEmits可以用于声明对父组件上的一个或多个监听事件的触发,并返回一个触发函数对象emit。

下面是声明方式:

const emits = defineEmits(['increase']);
// 声明多个触发
const emits = defineEmits(['increase', 'emit2', 'emit3']);

如何使用触发?

// 要触发哪个监听事件,就传入对应的事件名
emits('increase');
emits('emit2');
2.3 说明

关于emits()的参数:

  • 第一个参数,是监听事件的字面量(即名称)。
  • 第二个参数为事件传递的参数。如果该事件有多个参数,第二个参数建议用对象的形式传递。

例如:

//子组件发送,传递两个参数
emits('increase', {params1:'1',params2:'2'});
...
//父组件监听事件的处理函数
const handleIncrease = (params) => {
	console.log(params.params1, params.params2);//{'1','2'}
	nums.value += datas;
};

3.$ref + defineExpose

这种方法通常用于实现父子组件之间的通信。

在 vue2 中,有时候想访问$refs绑定的组件的属性或者方法,我们会使用 $refs。

但在 vue3 中,由于在 setup 中无法访问到 this,所以这种方式是不适用的!那么为了能够使用 $refs,我们需要借助一个方法:getCurrentInstance()。该对象返回当前的实例对象,但在使用该方法时,需要注意:

  • 不要将该函数当作一个 optionsApi 来获取 this
  • 该方法仅在 setup、生命周期函数中有效,在方法中是无效的。
3.1 实例

父组件

<!-- 父组件 -->
<template>
    <div>
        <Child ref="child"></Child>
        <button @click="show">Show Child Message</button>
    </div>
</template>


<script setup>

import { getCurrentInstance } from '@vue/runtime-core';
import Child from './Child.vue';

const currentInstance = getCurrentInstance()

function show() {
    currentInstance.ctx.$refs.child.alertMessage()
}

</script>

子组件

<!-- 子组件 -->
<template>
    <div>
        <h1>{{ message }}</h1>
    </div>
</template>

<script setup>
import { ref } from '@vue/reactivity';

let message = ref('我是子元素').value

const alertMessage = function () {
    alert(message)
}

//向外暴露指定属性
defineExpose({
    message,
    alertMessage
})
</script>

这里需要注意的是:在使用<script setup>语法糖时,组件是默认关闭的,即:在父组件中通过$refs来访问子组件中的值或在子组件中通过$parents来访问父组件中的值时,都是取不到的!必须通过defineExpose暴露对应值后,才可以被访问到。

3.2 说明

实际上,在开发中,上面使用$refs的方式并不多见,因为其必须要依靠getCurrentInstance()方法。

使用较多的是下面这种方法:

<template>
<div><input type="text" ref="txt1" value="hello" /></div>
</template>

<script>
import { defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
  	const txt1 = ref();

	const test = () => {
		console.log(txt1.value.value);
	}
	
	return {
		txt1,//一定不要忘记在return中返回给外部,因为这里相当于是声明一个响应式对象txt1,然后将其返回,并在模板中将其绑定为DOM元素的ref。
		test
	}
  }
});
</script>

或者可以这样:

<template>
<div><input type="text" ref="txt1" value="hello" /></div>
</template>

<script setup>
import { defineComponent, ref } from "vue";

const txt1 = ref();
const test = () => {
	console.log(txt1.value.value);
}
</script>

即在<script setup>语法糖中,可以不用返回,因为其中的值为自动返回。

接下来就可以通过声明的响应式对象来使用对应组件中通过defineExpose暴露出来的属性了!

4.其它方法

vue3中除了以上三种组件间通信的方式,还有其它可以实现组件间通信的方法:

  • v-model
  • 依赖注入 provide / inject
  • eventBus
  • vuex

其中,v-model 并不能严格成为数据的传递方式,其实只是减少了代码量。

而关于 eventBus,虽然 vue3 中将其移除,但仍然可以通过第三方插件来使用。

还有 provide / inject,关于这个我会有单独的一篇文章进行介绍,因为我自身也没怎么接触过。

最后就是 vuex ,vue 的状态管理工具,基本上是项目里面必然会用到的,这里就不说了。

Vue 3组件通信13种方法 在 Vue 3 中,组件之间的通信是构建应用程序的关键。本指南将介绍 13 种不同的组件通信方法,从最简单到最复杂,帮助你选择最适合你需求的方式。这 13 种方法涵盖了 Vue 3 中几乎所有的组件通信场景。根据你的具体需求和应用规模,选择最合适的通信方式。记住,好的组件设计能够简化通信,提高代码的可维护性。 阅读详情

相关推荐

极速上手 VUE 3——teleport传送门组件

第一个挂载元素第二个挂载元素运行结果如图:上边的实例等价于:第一个挂载元素第二个挂载元素二、为什么使用 teleport使用 vue 开发时,都是多个组件之间不断地嵌套,处理元素的样式或者层级的时候就会变得困难。如我们需要添加一个 modal 模态框或 toast 提示框,如果我们把这样的框可以从 vue 组件中剥离出来,我们样式和层级设置起来会更加简便。有些同学会想,这直接放到 index.html 中不就好了吗?

2401_84433829的博客 1398

vue3 组件之间的通信

vue3 组件之间的通信

Tianxiaoxixi的博客 8535

2024前端面试系列——Vue面试题_描述下 vue 从初始化页面--修改数据--刷新页面 ui 的过程

但是在 Vue 中,由于模板中使用的数据都必须挂在 this 上进行一次中转,所以我们 import 一个组件完了之后,还需要在 components 中再声明下,这样显然是很奇怪但又不得不这样的做法。这里不推荐直接用 nuxt.js 服务端渲染方案,因为这样一来增加了学习成本,二来服务端的维护成本也会上升,有时在本机测试没问题,在服务端跑就有问题,为了省心,还是最大限度的使用静态页面较好。这是因为 Vue 和 React 设计理念上的区别,Vue 使用的是可变数据,而 React 更强调数据的不可变。

2401_84419493的博客 1203

Vue3中常用的八种组件通信方式

点击我触发自定义事件xxx

weixin_74009702的博客 6732

Vue笔记2+3

计算属性 作用:为了将不经常变化的计算结果进行保存 计算属性不能和方法同名,不然会调用到同名方法。

sunburstm的博客 867

五、vue3.0之组件通信详解(defineProps、defineEmits、defineExpose)

web前端vue3.2之组件通信详解(defineProps、defineEmits、defineExpose)

张先森的博客 2万+

Vue Provide / Inject 详细介绍(跨组件通信、响应式变化、版本变化)

背景 通常,当我们需要从父组件向子组件传递数据时,我们使用props。想象一下这样的结构:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 prop 沿着组件链逐级传递下去,可能会很麻烦。 对于这种情况,我们可以使用一对provide和inject。无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。这个特性有两个部分:父组件有一个provide选项来提供数据,子组件有一个inject选项来开始使用这些数据。 使用 假设有一个组件...

高大志leo的博客 2万+

Vue3 学习——基础知识学习与项目实操

Vue 基础学习与项目实操。包括创建 Vue 组件、实现各组件间交互、路由跳转等基础 Vue 知识的介绍与实现。

敲代码的小李同学的博客 1339

简记Vue3(五)—— 组件通信(props、自定义事件、mitt、v-model、$attrs、$refs、$parent、provide、inject、插槽)

本篇文章我们学习Vue3中组件间的通信方式,包括props、自定义事件、mitt、v-model、$attrs、$refs、$parent、provide、inject、插槽等。

HuoZhiyan 的博客 1292

专治疑难系列 - 解决打印机凭证冲突问题

一、问题描述 二、解决方法 三、问题已解决

Passerby_Wang的博客 2万+

Python实战:逐笔高频因子构建与回测全流程解析

本文详细解析了使用Python构建与回测逐笔高频因子的全流程。从逐笔数据的价值与清洗入手,通过实战代码演示了‘大买成交金额占比’因子的计算逻辑,并重点阐述了因子正交化处理的重要性以剔除风格影响。最后,提供了一个经典的分位数回测框架来验证因子有效性,并分享了数据质量、计算效率与过拟合等核心避坑指南。

grass的博客 391

Vue3组件通信

Vue3组件通信

chujian0325的博客 908

多期DID实战指南:从CSDID原理到分组加权策略

本文深入解析多期DID(CSDID方法)在政策评估中的实战应用,从核心思想到分组加权策略全面讲解。通过电商扶贫等案例,详细演示如何正确处理分批实施政策的数据分析,包括分组拆解、子模块DID操作及加权平均选择,帮助研究者规避常见误区,提升政策评估的准确性。

weixin_26833503的博客 524

【vue3】composition-api使用

markRaw 永远不会转为响应式代理 const target = ref(markRaw(window)); // 永远不会转为响应式代理 return { target }; store的使用 import { useStore } from 'vuex' const store = useStore() onBeforeMount(() => { store.commit('setShowBack', false) }) router的使用 import { useSto.

越思考越清晰 4171

ADS谐波平衡仿真自动优化报错?三步搞定HB控件设置(附常见错误排查)

本文针对ADS谐波平衡仿真在自动优化中常见的报错问题,提供了三步核心排查法。首先检查并禁用HB控件中可能导致冲突的小信号仿真模式,其次合理化仿真频率与扫描参数设置,最后审视优化变量与目标的定义。通过精准配置HB控件以适配自动优化流程,能有效解决大多数仿真失败问题,确保非线性电路设计顺利进行。

c2d3e4f的博客 789

浙政钉H5应用上架实战:从环境配置到发布避坑指南

本文详细解析浙政钉H5应用上架全流程,从环境配置到发布避坑指南。重点介绍Vue 2.6 + Node 14.21.3的稳定开发环境搭建、项目结构规范及常见报错解决方案,帮助开发者高效完成浙政钉H5应用上架流程。

weixin_27943395的博客 286

总结vue3常用的基础语法

vue3常用的基础语法包括:列表的渲染、条件判断、样式绑定、vue指令、表单事件处理、响应式数据、生命周期、watch监听、计算属性computed()、组件的基础。

luguanyou的博客 2837

Matlab实战:用DQN算法让机器人学会自主避障(附完整代码)

本文详细介绍了如何使用Matlab实现DQN(深度Q网络)算法,使机器人在复杂环境中学会自主避障。通过环境建模、网络架构设计、奖励函数优化及实战调试,提供了完整的代码实现和训练策略,帮助开发者快速应用于机器人路径规划项目。

t8u9v0w1x的博客 232

Vue3基础(API风格、监听、生命周期、toRefs、组件通信、插槽、axios,Promise)

watchEffect函数不用指定监听谁,只要watchEffect内部用了某个变量,某个变量发送变化,就会触发。toRefs的作用将一个包含响应式对象属性的普通对象转换为包含 ref 对象的普通对象,通俗一点就是。都适用于不同场景,生产项目中,低复杂度场景用选项式API,单页应用用组合式API+单文件组件。函数用于监视一个数据,并在数据变化时执行特定的逻辑。该方法也是Vue2中所使用的,其特点是例如。等对象所定义的属性都会暴露在函数内部的。单文件组件中组合式API通常和。上,它会指向当前的组件实例。

AZURE060606的博客 1525

Fluent新手避坑:遇到‘Floating point exception’别慌,这7个排查步骤帮你搞定

本文为Fluent新手提供了7个排查'Floating point exception'错误的实用步骤,包括边界条件检查、时间步长优化、求解器配置等关键技巧。通过系统化的诊断流程,帮助用户快速定位并解决CFD仿真中的浮点异常问题,提升计算稳定性。

weixin_42531886的博客 286

LAMMPS实例教程—In文件详解

本博文主要介绍专栏 《LAMMPS实例教程—In文件详解》, 针对于 Lammps 可分析的物理过程进行讲解,提供 In 文件以及后处理方法,持续更新。 目前分为8个专题: 1)力学专题、2)传热专题、3)相变专题、4)界面专题、5)吸附专题、6)流动专题、7)物性专题以及8)基础理论专题。

Rockyoung 3万+

Vue项目实战——实现一个任务清单【基于 Vue3.x 全家桶(简易版)】

Vue项目实战——实现一个任务清单【基于 Vue3.x 全家桶(简易版)】

HuoZhiyan 的博客 5676

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

X-BUILD插件系统揭秘:如何基于mitt实现组件间通信的终极指南

在Vue 3时代,组件间通信变得更为灵活但也更具挑战性。X-BUILD作为一款基于Vite2 + Vue3 + TypeScript的前端脚手架,巧妙地利用mitt库解决了这一难题,为开发者提供了简单高效的组件通信方案。本文将深入揭秘X-BUILD的插件系统,并详细讲解如何基于mitt实现优雅的组件间通信。 ## 🔥 为什么选择mitt作为通信方案? Vue 3移除了`$on`、`$off`

gitblog_01074的博客 425

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Vue3.x全家桶之Vue组件化开发(二)

✍ 1、组件化开发 我们将一个完整的页面分成很多个组件,每个组件都用于实现页面的一个功能块,而每一个组件又可以进行细分 1.1、组件的使用 步骤: 创建组件构造器: 调用 Vue.extend() 方法创建组件构造器 注册组件:调用 Vue.component() 方法注册组件 使用组件:在 Vue 实例的作用范围内使用组件 <div id="app"> <!--3.使用组件--> <my-cpn></my-cpn> <my-cpn&g

Augenstern_QXL的博客 3347

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

leaflet+vue实现webgis小系统(附源码下载)

这个是在我前面写的博库leaflet+geoserver+jquery基础上进行了一点调整,将jquery框架拆解替换为Vue3,我们都知道Vue框架适用于项目中有多个部分是相同的,并可以封装成一个组件,但是针对我这个小demo-webgis系统来说,使用vue3真实大材小用了,里面涉及到组件间通信(使用了大量的inject,provide),拆分成多个组件需要使用Hook函数封装公共方法将结果暴露出去。最后只能拆解1/3,因为到后面做不下去了,主要是自己太菜鸡了,拆解的组件和Hook方法如下图所示:

你们瞎搞 1038

学习vue3 三,组件基础,父子组件传值

通过defineProps方法,参数传一个对象,将要接受的数据通过属性的方式写入,如果要进行一些配置也可以使用对象的形式进行配置,如title。注意需要在onMounted里打印的原因是,setup的生命周期早于子组件挂载,也就是子组件还没有挂载就打印输出所以会是undefined。是通过defineEmits派发一个事件,绑定一个自定义事件,通过一些vue有的事件去触发这个emit从而达到传值的目的。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。

tian_liang_jia的博客 947
上一篇: 【Vue3基础】ref 和 reactive
下一篇: 【JS进阶】显式绑定与硬绑定
cannotbecounted
博客等级 码龄7年 101粉丝 59原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值