vue3组件通信(父给子传参,子调用父的方法,父调用子的方法,顶层组件给底层组件传参,底层组件调用顶层组件的方法)

目录

1.父传子(父给子传参)

2.子传父(子调用父的方法)

3.父调用子的方法

4.顶层给底层传参,底层调用顶层的方法

5.模板引用


1.父传子(父给子传参)

①.步骤

父组件中给子组件通过绑定属性的方式传递往子组件的参数

子组件内部通过props选项进行接收

②.示例

父组件:

<script setup>
// 局部组件,导入之后就可以进行使用
import chlid from '@/components/child.vue'
import { ref } from 'vue';
const money = ref(50);
const add = () =>{money.value += 10;
}
</script><template><div><h3>父组件 {{ money }}<!-- 在父组件中改变了往子组件传递的值,子组件会接收到最新的值,并更新视图 --><button @click="add"> 挣钱</button></h3><!-- 给子组件,以添加属性的方式进行传递,可以传递固定值或者动态值--><chlid car = "BYD" :money = "money"></chlid></div>
</template>

子组件:

<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"> 子组件  {{ car }} - {{ money }} 
<button>花钱</button>
</div>
</template><script setup>
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>

③.说明

在父组件中,导入子组件可以直接进行使用。

在父组件中,需要在子组件上以属性的方式进行参数传递,可以传递固定值或者动态值。

在父组件中,改变了给子组件传递的值,子组件会实时接收到最新的值,并更新视图。

在子组件中,通过defineProps来接收父组件传递的参数,参数id和父组件中子组件上的属性一致。

在子组件中,模板中可以直接使用参数,在js中要通过对象.属性的方式进行使用。

2.子传父(子调用父的方法)

①步骤

在父组件中给子组件标签通过@方式绑定自定义事件

在子组件通过defineEmits编译器宏生成emit方法

在子组件中触发自定义事件,并传递参数

②示例

父组件:

<script setup>
// 局部组件,导入之后就可以进行使用
import chlid from '@/components/child.vue'
import { ref } from 'vue';
const money = ref(50);
const add = () =>{money.value += 10;
}const subs = (val) =>{
money.value = val;
}
</script><template><div><h3>父组件 {{ money }}<!-- 在父组件中改变了往子组件传递的值,子组件会接收到最新的值,并更新视图 --><button @click="add"> 挣钱</button></h3><!-- 给子组件,以添加属性的方式进行传递,可以传递固定值或者动态值--><chlid car = "BYD" :money = "money" @sub="subs"></chlid></div>
</template>

子组件:

<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"> 子组件  {{ car }} - {{ money }} 
<button @click="send">花钱</button>
</div>
</template><script setup>
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)const send = () =>{emit("sub",5);
}</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>

③说明

父组件中的自定义事件名和子组件中defineEmits数组中的时间名和emit方法中的事件名,这三个事件名必须保持一致。

3.父调用子的方法

①步骤

默认情况下载<script setup>语法糖下组件内部的属性和方法时不开放给父组件访问的,

可以通过defineExpose编译宏指定哪些属性和方法允许访问。

②示例

父组件:

<script setup>
// 局部组件,导入之后就可以进行使用
import chlid from '@/components/child.vue'
import { ref } from 'vue';
const name = ref('xiaolin');
const updateName = () => {name.value = 'xiaoli';
}
const money = ref(50);
const add = () =>{money.value += 10;
}const subs = (val) =>{
money.value = val;
}// 定义子组件ref对象,调用子组件的方法及属性
const childRef = ref(null);
const gerChild = () =>{console.log(childRef.value);console.log(childRef.value.info);childRef.value.fun1('123');
}
</script><template><div><h3>父组件 {{ money }}<!-- 在父组件中改变了往子组件传递的值,子组件会接收到最新的值,并更新视图 --><button @click="add"> 挣钱</button></h3><!-- 给子组件,以添加属性的方式进行传递,可以传递固定值或者动态值--><chlid ref="childRef" car = "BYD" :money = "money" @sub="subs"></chlid><button @click="gerChild">获取子组件</button></div>
</template>

子组件:

<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"> 子组件  {{ car }} - {{ money }} 
<button @click="send">花钱</button>
<input ref="inputRef"/>
</div>
</template><script setup>
import { ref,onMounted } from 'vue';
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)const send = () =>{emit("sub",5);
}
// 模板引用
// 1.通过调用ref函数生成一个ref对象
// 2.通过ref标识进行绑定
// 通过ref对象的.value属性就能获取到绑定元素或组件的方法及属性(必须渲染完成之后才能获取)
const inputRef = ref(null);
onMounted(()=>{console.log(inputRef.value);inputRef.value.focus();
})// 下面的属性和方法要想被父组件访问,需要defineExpose宏函数指定要访问的属性和方法
const  info = 1234556;
const fun1 = (val) =>{console.log("调用到了子组件的方法",val);
}
defineExpose({info,fun1
})
</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>

③说明

通过defineExpose显示暴露子组件内部的属性和方法。

在父组件中通过ref函数获取到子组件的实例,然后通过.value来调用子组件的属性及方法。

4.顶层给底层传参,底层调用顶层的方法

①步骤

顶层组件通过provide函数提供数据

底层组件通过inject函数获取数据

传递参数,一般传递响应式变量

传递方法,方法中可以接收参数 

②示例

顶层组件

<script setup>
// 局部组件,导入之后就可以进行使用
import chlid from '@/components/child.vue'
import { provide, ref } from 'vue';
const name = ref('xiaolin');
const updateName = () => {name.value = 'xiaoli';
}
const money = ref(50);
const add = () =>{money.value += 10;
}const subs = (val) =>{
money.value = val;
}// 定义子组件ref对象,调用子组件的方法及属性
const childRef = ref(null);
const gerChild = () =>{console.log(childRef.value);console.log(childRef.value.info);childRef.value.fun1('123');
}
// 顶层组件给底层组件传递参数
// 在顶层组件通过provie向底层组件传递参数,数据是响应式的,在顶层组件中修改了传递给底层组件的参数,底层组件会接收到最新的值。
const title= ref("主题1");
provide("title",title);
const updateBottom = () =>{title.value = "主题修改了";
}
// 顶层组件给底层组件传递方法
provide('updateTitile', (newVal) =>{title.value = '主题修改为' + newVal;
})
</script><template><div><h1>父组件 {{ money }}<!-- 在父组件中改变了往子组件传递的值,子组件会接收到最新的值,并更新视图 --><button @click="add"> 挣钱</button></h1><!-- 给子组件,以添加属性的方式进行传递,可以传递固定值或者动态值--><chlid ref="childRef" car = "BYD" :money = "money" @sub="subs"></chlid><button @click="gerChild">获取子组件</button><!-- 修改向底层组件传递的内容 --><button @click="updateBottom"> 修改向底层组件传递的内容</button></div>
</template>

中间组件

<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"><h2>子组件  {{ car }} - {{ money }} </h2>
<button @click="send">花钱</button>
<input ref="inputRef"/>
<bottom></bottom>
</div></template><script setup>
import { ref,onMounted } from 'vue';
import bottom from './bottom.vue';
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)const send = () =>{emit("sub",5);
}
// 模板引用
// 1.通过调用ref函数生成一个ref对象
// 2.通过ref标识进行绑定
// 通过ref对象的.value属性就能获取到绑定元素或组件的方法及属性(必须渲染完成之后才能获取)
const inputRef = ref(null);
onMounted(()=>{console.log(inputRef.value);inputRef.value.focus();
})// 下面的属性和方法要想被父组件访问,需要defineExpose宏函数指定要访问的属性和方法
const  info = 1234556;
const fun1 = (val) =>{console.log("调用到了子组件的方法",val);
}
defineExpose({info,fun1
})
</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>

底层组件

<template>
<div> <h3>我是底层组件 - {{ title }}</h3><button @click="update">调用顶层组件的方法</button>
</div>
</template><script setup>
import { inject } from 'vue';// 底层组件通过inject接收顶层组件的参数
const title = inject('title');// 底层组件通过inject接收顶层组件的方法
const updateTitile = inject('updateTitile');const update = () =>{updateTitile('底层调用顶层');
}</script>

③说明

通过provide及inject实现顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信。如果不使用这种方式,只能一级级组件进行通信,或者使用全局状态管理(如pinia)。

在顶层组件中通过provide提供响应式变量及方法,在底层组件中铜鼓inject可以进行调用。

5.模板引用

①步骤

调用ref函数生成一个ref对象。

通过ref标识绑定ref对象到标签中。

②示例

<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"> 子组件  {{ car }} - {{ money }} 
<button @click="send">花钱</button>
<input ref="inputRef"/>
</div>
</template><script setup>
import { ref,onMounted } from 'vue';
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)const send = () =>{emit("sub",5);
}
// 模板引用
// 1.通过调用ref函数生成一个ref对象
// 2.通过ref标识进行绑定
// 通过ref对象的.value属性就能获取到绑定元素或组件的方法及属性(必须渲染完成之后才能获取)
const inputRef = ref(null);
onMounted(()=>{console.log(inputRef.value);inputRef.value.focus();
})const  info = 1234556;
const fun1 = () =>{console.log("调用到了子组件的方法");
}
</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>

上面示例实现了画面加载后焦点放在输入框上。 

③说明

通过ref标识获取真实的dom对象或者组件对象实例,这就就通过dom对象或者组件实例来调用方法和属性。常见的示例如下:

获取form表单的dom对象,调用validate()进行校验处理。

获取imput输入框的dom对象,调用focus(),将焦点放在输入框上。

获取子组件的对象实例,调用子组件的方法或者获取子组件的属性。

注意:通过ref方式获取dom对象有一个前提,必须是页面渲染完成之后才能获取到,最早在onmounted中可以获取到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/298384.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

48V转12V 300mA降压芯片,60V耐压、0.6A稳压芯片带ECO模式-AH590L

AH590L是一种48V转12V 300mA降压芯片&#xff0c;具有60V耐压、0.6A稳压电流的特点&#xff0c;并且还带有ECO模式&#xff0c;是一种理想的开关电源解决方案。 AH590L是PWM模式 DC/DC降压转换器。TEL&#xff1a;l86*4884*3702*宽输入电压范围4至60V适用于工业领域的广泛应用…

Java版企业电子招投标系统源代码,支持二次开发,采用Spring cloud微服务架构

在数字化时代&#xff0c;企业需要借助先进的数字化技术来提高工程管理效率和质量。招投标管理系统作为企业内部业务项目管理的重要应用平台&#xff0c;涵盖了门户管理、立项管理、采购项目管理、采购公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理等…

服务器扩容未生效、不成功:解决方法

记一次解决服务器扩容未生效的解决办法 老板&#xff1a;失忆啊&#xff0c;我花钱给服务器扩容了10000000G&#xff0c;但是数据库和mq都还是用不了&#xff0c;到底是不是服务器磁盘满了&#xff0c;你到底有没有查一下什么原因导致服务用不了啊。 失忆&#xff1a;老板您确…

利用vb开发图片加密软件怎么样?

随着科技的发展&#xff0c;图片加密软件已经成为了我们生活中不可或缺的一部分。它不仅可以保护我们的隐私&#xff0c;还可以防止我们的图片被不法分子盗用。那么&#xff0c;如果我们利用VB(Visual Basic)来开发这样的软件会怎样呢&#xff1f;本文将从技术可行性、开发难度…

免费福利马上截止!深圳的户外小伙伴别错过!COSP2024体育展来了

COSP2024户外博览会 展会时间&#xff1a;2024年3月14-16日 展会地址&#xff1a;深圳福田会展中心 户外运动爱好者不可错过&#xff01; COSP2024户外博览会不仅可以逛展 看各种露营装备、户外器材 还有各种沙龙、峰会活动 就在明年开年&#xff0c;阳春三月天&#xf…

西门子PLC通过PROFINET协议与多功能电表通讯

西门子PLC通过PROFINET协议与多功能电表通讯 项目要求 西门子S71200PLC需要通过PROFINET协议和多功能电表通讯&#xff0c;读取线电压、相电压、线电流、相电流、有功功率、无功功率等参数。 项目实施 采用网关NET90-PN-MBT&#xff08;以下简称“网关”&#xff09;&#…

WebGL技术实现机械工程培训

机械工程培训的虚拟环境可以通过 WebGL 技术实现&#xff0c;提供沉浸式的三维体验&#xff0c;帮助学生学习机械结构、运动原理和装配过程。以下是开发机械工程培训虚拟环境的一般步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发…

VR全景对普通人的生活有哪些好处?

许多普通人对VR全景还全然没有概念&#xff0c;这是因为VR全景虽然一直在快速发展&#xff0c;但目前为止也不过几年而已&#xff0c;但这发展的几年同样为我们普通人的生活带来了切实的改变和便利。VR全景技术为人们带来了沉浸感和真实感的体验&#xff0c;让我们感受到迥异于…

Unity程序向Web服务器发送数据

Unity程序向Web服务器发送数据 一、介绍二、HTTP协议三、新建Unity工程&#xff0c;创建脚本1.新建Unity工程&#xff0c;创建脚本WebManager.cs&#xff0c;将其指定给场景中的任意游戏体。2.在WebManager.cs中添加一个m_info属性和OnGUI函数显示UI&#xff1a; 四、GET请求在…

倾斜摄影三维模型数据在行业应用分析

倾斜摄影三维模型数据在行业应用分析 倾斜摄影三维模型数据是一种重要的地理信息资源&#xff0c;可以广泛应用于各个行业和场景&#xff0c;以解决不同领域的问题。以下将详细探讨几个典型的行业或场景&#xff0c;它们利用倾斜摄影三维模型数据解决问题的应用。 1、地理测绘…

游戏软文推广:软文推广如何点燃玩家热情

在数字化时代&#xff0c;随着科技的迅猛发展&#xff0c;游戏产业日益蓬勃&#xff0c;成为了娱乐市场中的一匹黑马。而在游戏行业中&#xff0c;软文推广逐渐成为一种有效而巧妙的宣传手段。本文将深入探讨游戏软文推广的潜力&#xff0c;以及通过这种方式所能够达到的宣发效…

springboot整合JPA 多表关联 :一对多 多对多

补充一下自定义SQL 这是连表查询&#xff0c;可以任意查出字符&#xff0c;用Map接收 Testvoid test3() {JPAQueryFactory jpaQueryFactory new JPAQueryFactory(em);QStudent student QStudent.student;QMessage message QMessage.message;//constructor(StuMesDto.class, …