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中可以获取到。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

收银管理系统怎样帮助商家很好地经营服装门店

收银管理系统对于服装门店的经营可以提供多方面的帮助&#xff0c;以下是一些具体的优势和功能&#xff1a; 1. 快速准确的收银&#xff1a;收银管理系统可以实现快速、准确的收银操作&#xff0c;通过条码扫描或手动输入商品信息&#xff0c;自动计算价格并生成收据。这样可以…

nacos配置中心配置已经常见错误总结

&#x1f4bb;目录 前言1、基础架构2、依赖3、配置文件3.1、bolg-product配置文件3.1.1、application.yml配置文件3.1.2、bootstrap.yml配置文件3.1.3、nacos远程配置 3.2、bolg-system3.1.1、application.yml配置文件3.1.2、bootstrap.yml配置文件3.2.3、nacos远程配置 4、测试…

【文本处理】正则表达式

一、简介 正则表达式&#xff0c;又称规则表达式,&#xff08;Regular Expression&#xff0c;在代码中常简写为regex、regexp或RE&#xff09;&#xff0c;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特殊字符&…

在Redis客户端设置连接密码 并演示密码登录

我们先连接到Redis服务 然后 我们要输入 CONFIG SET requirepass “新密码” 例如 CONFIG SET requirepass "A15167"这样 密码就被设置成立 A15167 我们 输入 AUTH 密码 例如 AUTH A15167这里 返回OK说明成功了 然后 我们退出在登录就真的需要 redis-cli -h IP地…

嵌入式开发——PWM高级定时器

学习目标 加强掌握PWM开发流程理解定时器与通道的关系掌握多通道配置策略掌握互补PWM配置策略掌握定时器查询方式掌握代码抽取优化策略掌握PWM调试方式学习内容 需求 点亮8个灯,采用pwm的方式。 定时器 通道 <

vue3 新项目 - 搭建路由router

创建router/index 文件 main.ts 安装 router 然后 在 app下面 去 设置 路由出口

【贪心】买卖股票的最佳时机含手续费

/** 贪心&#xff1a;每次选取更低的价格买入&#xff0c;遇到高于买入的价格就出售(此时不一定是最大收益)。* 使用buy表示买入股票的价格和手续费的和。遍历数组&#xff0c;如果后面的股票价格加上手续费* 小于buy&#xff0c;说明有更低的买入价格更新buy。如…

深度神经网络下的风格迁移模型(C#)

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 这个是C#版本的&#xff0c;这里就只放出代码。VB.Net版本请参看 深度神经网络下的风格迁移模型-CSDN博客 斯坦福大学李飞飞团队的…

智能优化算法应用:基于天鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于天鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于天鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.天鹰算法4.实验参数设定5.算法结果6.参考文献7.MA…

Unity PlayerPrefs存储数据在Windows环境中本地存储的位置

Unity PlayerPrefs存储数据在Windows环境中本地存储的位置 一、编辑器模式下的PlayerPrefs存储位置1.Win r 输入regedit进入注册表界面2. HKEY_CURRENT_USER/Software/Unity3.CompanyName和ProjectName可以在Unity->Edit->Project Settings->Player中查看和设置 二、…

Vue3数据交互axios

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

Git系统有哪些优势

在现在的这个软件开发领域&#xff0c;版本控制是一项非常重要的工作。Git作为比较流行的分布式版本控制系统&#xff0c;他有着独特的优势成为了很多开发者们的首选。那Git系统都有哪些优势呢&#xff0c;下面我以自己的理解简单的介绍一下。 分布式版本控制的优势 Git用的是…

Java多线程、线程池及线程同步(synchronized关键字、悲观锁、乐观锁)

1.进程与线程定义 进程包含线程&#xff0c;如一个百度网盘进程&#xff0c;该进程的线程可以有上传&#xff0c;下载。 2.创建线程的三种方式 方式1-继承Thread类 方式2-实现Runnabled接口 1.常规写法 2.匿名内部类写法 方式3-实现Callable接口 示例代码&#xff1a; f1.get…

nginx 利用 error_page 实现自定义 404 跳转

文章目录 [toc]指定错误代码的 url 路径使用 response 来更改状态码使用 URL 重定向开始搞事情创建一个 404 文件配置 conf 文件通过 CURL 命令验证 error_page 以下内容&#xff0c;摘抄翻译自官网 语法格式 - error_page code ... [[response]] uri;上下文 - http, server, l…

【数据结构入门精讲 | 第十篇】考研408排序算法专项练习(二)

在上文中我们进行了排序算法的判断题、选择题的专项练习&#xff0c;在这一篇中我们将进行排序算法中编程题的练习。 目录 编程题R7-1 字符串的冒泡排序R7-1 抢红包R7-1 PAT排名汇总R7-2 统计工龄R7-1 插入排序还是堆排序R7-2 龙龙送外卖R7-3 家谱处理 编程题 R7-1 字符串的冒…

SpringSecurity6 | 失败后的跳转

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏: MySQL学习 🥭本文内容: SpringSecurity6 | 失败后的跳转 📚个人知识库: Leo知识库,欢迎大家访问 学习…

rk3588 之启动

目录 uboot版本配置修改编译 linux版本配置修改编译 启动sd卡启动制作spi 烧录 参考 uboot 版本 v2024.01-rc2 https://github.com/u-boot/u-boot https://github.com/rockchip-linux/rkbin 配置修改 使用这两个配置即可&#xff1a; orangepi-5-plus-rk3588_defconfig r…

高级人工智能之群体智能:蚁群算法

群体智能 鸟群&#xff1a; 鱼群&#xff1a; 1.基本介绍 蚁群算法&#xff08;Ant Colony Optimization, ACO&#xff09;是一种模拟自然界蚂蚁觅食行为的优化算法。它通常用于解决路径优化问题&#xff0c;如旅行商问题&#xff08;TSP&#xff09;。 蚁群算法的基本步骤…

【C->Cpp】深度解析#由C迈向Cpp(2)

目录 &#xff08;一&#xff09;缺省参数 全缺省参数 半缺省参数 缺省参数只能在函数的声明中出现&#xff1a; 小结&#xff1a; &#xff08;二&#xff09;函数重载 函数重载的定义 三种重载 在上一篇中&#xff0c;我们从第一个Cpp程序为切入&#xff0c;讲解了Cpp的…

Topaz Video AI 视频修复工具(内附安装压缩包win+Mac)

目录 一、Topaz Video AI 简介 二、Topaz Video AI 安装下载 三、Topaz Video AI 使用 最近玩上了pika1.0和runway的图片转视频&#xff0c;发现生成出来的视频都是有点糊的&#xff0c;然后就找到这款AI修复视频工具 Topaz Video AI。 一、Topaz Video AI 简介 Topaz Video…