[Vue3]父子组件相互传值数据同步

news2024/11/29 1:29:03

简介

vue3中使用setup语法糖,父子组件之间相互传递数据及数据同步问题

文章目录

  • 简介
  • 父传子
    • props传递值 使用v-bind绑定
      • props需要计算
        • toRef
        • computed
    • emit传递方法 使用v-on绑定
  • 子传父
    • expose
  • v-model
  • 总结


父传子

props传递值 使用v-bind绑定

父组件通过props给子组件传递值,props传递的值在子组件中无法修改

// 父组件
<template>
	<div style="color: red">
		 我是父组件
		 <Child :msg="msg"></Child>
	</div>
</template>
 
<script setup>
    import Child from './Child.vue';
    import { ref } from 'vue';
    const msg = ref('111');
</script>
// 子组件
<template>
  <div style="color: blue">
    <div>我是子组件, 父组件传递来的值是{{msg}}</div>
  </div>
</template>

<script setup>
	defineProps({
	  msg: String,
	})
</script>

在这里插入图片描述

props需要计算

子组件获取props后,需要显示根据其计算后的值,而props是无法修改的。

toRef

这里有可能会出现子组件只能取到props的初始值,如果props变化子组件不会更新:

// 父组件
<script setup>
  import Child from './Child.vue';
  import { ref } from 'vue';
  const msg = ref('111');
</script>

<template>
  <div style="color: red">
    我是父组件
    {{ msg }}
    <Child :msg="msg"></Child>
    <button @click="() => msg = '222'">父组件点击改变props值</button>
  </div>
</template>
// 子组件
<script setup>
  import { ref } from 'vue'
  const props = defineProps({
    msg: String,
  })
  const a = ref(props.msg);
</script>

<template>
  <div style="color: blue">
    <div>我是子组件, 父组件传递来的值是{{a}}</div>
  </div>
</template>

点击按钮后,父组件传递的props改变,但是子组件接收到的却不变。
如果父组件中props没有赋初始值,在子组件中接收到的会是undifined。这是因为 ref 是对传入数据的拷贝,但 toRef 是对传入数据的引用。

// 子组件
  import { toRef } from 'vue'
  const props = defineProps({
    msg: String,
  })
  const a = toRef(props, 'msg');
  // const { msg } = toRefs(props); // 使用toRefs也可以

在这里插入图片描述

computed

根据props修改可以直接使用计算属性

// 父组件
<script setup>
  import Child from './Child.vue';
  import { ref } from 'vue';
  const msg = ref('A')
</script>

<template>
  <div style="color: red">
    我是父组件
    {{ msg }}
    <Child :msg="msg"></Child>
    <button @click="() => msg = 'B'">父组件点击改变props值</button>
  </div>
</template>
// 子组件
<script setup>
  import { computed } from 'vue'
  const props = defineProps({
    msg: String,
  })
  const a = computed(() => props.msg.trim().toLowerCase())
</script>

<template>
  <div style="color: blue">
    <div>我是子组件, 父组件传递来的值是{{ a }}</div>
  </div>
</template>

在这里插入图片描述

emit传递方法 使用v-on绑定

vue3中子组件想调用父组件传递的方法,需要使用defineEmits

// 父组件
<script setup>
  import { ref } from 'vue';
  import Child from './Child.vue';
  const a = ref('1');
  const handleTest = () => {
    a.value = 'change';
  }
</script>

<template>
  <div style="color: red">
    我是父组件
    <Child :msg="a" @test="handleTest"></Child>
  </div>
</template>
// 子组件
<script setup>  
  defineProps(['msg']);
  const emit = defineEmits(["test"])
  const handleClick = () => {
    emit("test")
  }
</script>

<template>
  <div style="color: blue">
    <div>我是子组件{{ msg }}</div>
    <button @click="handleClick">子组件调用父组件方法</button>
  </div>
</template>

在这里插入图片描述

emit的第一个参数是事件名,第二个参数是传递的参数。
这里如果父组件没有传递这个函数,也不会报错。

子传父

expose

父组件展示子组件的数据与方法,子组件需要通过defineExpose将自己的值暴露出来,父组件通过子组件上的ref取到其值

// 父组件
<script setup>
  import { ref, onMounted } from 'vue';
  import Child from './Child.vue';
  const a = ref('1');
  const x = ref();
  onMounted(()=>{
    a.value = x.value.message
  })
  const handle = () => {
    x.value.handleMessage();
  }
</script>

<template>
  <div style="color: red">
    我是父组件
    <Child ref="x"></Child>
    {{ a }}
    <button @click="handle">点击子组件触发事件</button>
  </div>
</template>
<script setup>
  import { ref } from "vue";
  const a = ref('我的值是1')
  const message = ref('我是子组件暴露的值');
  const handleMessage = () => {
    a.value = 'Change';
  }
  defineExpose({
    message,
    handleMessage
  });
</script>

<template>
  <div style="color: blue">
    我是子组件{{ a }}
  </div>
</template>

在这里插入图片描述
父组件调用子组件expose的值,一定要在onMounted之后,否则子组件没有完全加载,取不到值。
这种方法,如果子组件的值修改了,那么父组件也是拿不到的。

v-model

使用v-model可以实现父子组件之间值的同步。

// 父组件
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'

const msg = ref('Hello World!')
</script>

<template>
  <h1>{{ msg }}</h1>
  <Child v-model="msg" />
</template>
// 子组件
<script setup>
const model = defineModel()
</script>

<template>
  <span>My input</span> <input v-model="model">
</template>

在输入框中输入值,上面也会更新
defineModel是一个编译宏,它相当于:

// 子组件
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>

<template>
  <span>My input</span><input
    :value="props.modelValue"
    @input="emit('update:modelValue', $event.target.value)"
  />
</template>

所以 v-model如果没有另外声明,实际是给子组件设置了一个名为modelValue的props,一个update:modelValue的emit(注意注意,emit调用时第一个参数一定要跟define时相同,否则找不到,update:后面也不要加空格)。

v-model其实相当于v-bindv-on的组合:

<template>
  <h1>{{ msg }}</h1>
  <Child :modelValue="msg" @update:modelValue="val => msg= val"></Child>
</template>

v-model会将modelValue这个props和update:modelValue这个event绑定在一起。当子组件的值发生变化时,会触发update:modelValue 事件传递给父组件,父组件接收到事件后会更新自己的值并重新渲染子组件;当父组件的值发生变化时,会通过modelValue传递给子组件,子组件接收到 prop 后会更新自己的值并重新渲染。这样就实现了父子组件之间的数据同步。

v-model可以写成v-model:自定义='自定义',那么更新的值就是自定义,更新的函数就是 update:自定义

总结

  • 父传子:definePropsdefineEmits
  • 子传父:defineExpose
  • 双向绑定:v-bind

vue中父子传值的方法还是非常多的,但是其中不乏各种坑,新手还是应该老老实实用官方推荐,否则真的很难不踩坑,太灵活了有些时候也是一种问题呢(无语笑)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第三百零七回

文章目录 1. 概念介绍2. 使用方法3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何在输入框中提示错误"相关的内容&#xff0c;本章回中将介绍如何在输入框中处理光标.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在使用TextField组件作为…

【RT-DETR有效改进】UNetv2提出的一种SDI多层次特征融合模块(细节高效涨点)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 本问给大家带来的改进机制是UNetv2提出的一种多层次特征融合模块(SDI)其是一种用于替换Concat操作的模块,SDI模块的主要思想是通过整合编码器生成的层级特征图来增强图像中的语义信息和细节信息。包括皮肤…

远程连接服务器:Ping通但SSH连接失败的解决办法

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 前言常见问题影响SSH的因素本地影响因素防火墙设置网络配置文件 远程主机影响因素放行…

PyTorch 2.2 中文官方教程(二十)

移动设备 在 iOS 上进行图像分割 DeepLabV3 原文&#xff1a;pytorch.org/tutorials/beginner/deeplabv3_on_ios.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 作者&#xff1a;Jeff Tang 审阅者&#xff1a;Jeremiah Chung 介绍 语义图像分割是一种计算机视…

QCustomplot实现灰度曲线图

从 QCustomplot官网 https://www.qcustomplot.com/index.php/download 下载支持文件。首页有些demo可以进行参考学习。 新建一个Qt工程&#xff0c;将下载得到的qcustomplot.h和qcustomplot.cpp文件加入到当前工程。pro文件中加上 printsupport 在ui界面中&#xff0c;添加一…

Container 命令ctr、crictl 命令

1、 Containerd和Docker的架构区别 Docker vs. Containerd&#xff1a; 2、ctr & crictl的区别 ctr是containerd的一个客户端工具 crictl 是 CRI 兼容的容器运行时命令行接口&#xff0c;可以使用它来检查和调试 Kubernetes 节点上的容器运行时和应用程序 crictl 则直接对…

2024牛客寒假算法基础集训营1(视频讲解全部题目)

2024牛客寒假算法基础集训营1&#xff08;题目全解&#xff09; ABCDEFGHIJKLM 2024牛客寒假算法基础集训营1&#xff08;视频讲解全部题目&#xff09; A #include<bits/stdc.h> #define endl \n #define deb(x) cout << #x << " " << …

redis数据库设置对象的过期时间,到期后自动删除该条数据

redis数据库设置对象的过期时间,到期后自动删除该条数据&#xff01;过期时间的事情经常发生。比如大家领到了一些购物券。这张购物券有一个过期时间。必须在某节点之前&#xff08;某年某月末日&#xff09;之前&#xff0c;使用掉&#xff0c;否则该券就会过期&#xff0c;无…

ES高可用架构涉及常用功能整理

ES高可用架构涉及常用功能整理 1. es的高可用系统架构和相关组件2. es的核心参数2.1 常规配置2.2 特殊优化配置2.2.1 数据分片按ip打散2.2.2 数据分片机架感知2.2.3 强制要求数据分片机架感知2.2.4 写入线程池优化2.2.5 分片balance优化2.2.6 限流控制器优化 3. es常用命令3.1 …

超低价搭建cyberpanel+LiteSpeed企业版web服务器

注意&#xff0c;这里的企业版使用的是官方提供的免费密钥&#xff0c;在密钥激活后有一个月的有效时间&#xff0c;到期后官方会自动续期你的密钥 教学用配置&#xff1a; image1097698 126 KB 优惠链接&#xff1a;雨云 - 新一代云服务提供商 3 这是LiteSpeed&#xff08;以…

vue3 源码解析(5)— patch 函数源码的实现

什么是 patch 在 vue 中 patch 函数的作用是在渲染的过程中&#xff0c;比较新旧节点的变化&#xff0c;通过打补丁的形式&#xff0c;进行新增、删除、移动或替换操作&#xff0c;此过程避免了大量的 dom 操作&#xff0c;提升了运行的性能。 patch 执行流程 patch 函数整体…

0-MQTT基础使用教程【学习】

文件路径 MQTT基础使用教程1. MQTT1.1 MQTT简介1.1.1 什么是MQTT1.1.2 设计原则1.1.3 应用领域1.2 MQTT协议相关概念1.2.1 MQTT协议实现方式1.2.2 MQTT协议中的方法1.3 消息服务质量QoS1.3.1 消息服务质量QoS三个等级1.3.2 发布与订阅QoS1.4 Topic通配符匹配规则2. EMQX2.1 EMQ…

100183. 最大好子数组和

题目&#xff1a; 给你一个长度为 n 的数组 nums 和一个 正 整数 k 。 如果 nums 的一个子数组中&#xff0c;第一个元素和最后一个元素 差的绝对值恰好 为 k &#xff0c;我们称这个子数组为 好 的。换句话说&#xff0c;如果子数组 nums[i..j] 满足 |nums[i] - nums[j]| k…

Python基于时间序列分析的大气污染预测的设计与实现,附源码

1 简介 Python基于时间序列分析的大气污染预测的设计与实现 摘要&#xff1a;随着当今社会工业的发展&#xff0c;世界各地的空气质量都下降的非常明显&#xff0c;大气的污染对人们的身体健康会产生极大的危害。所以从20世纪初我国就十分关注空气质量的治理问题&#xff0c;…

【Java】Redis入门

1. Redis入门 1.1 Redis简介 Redis是一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。 官网&#xff1a;https://redis.io 中文网&#xff1a;https://www.redis.net.cn/ key-value结构存储&#xff1a; 主要特点&#xff1a; 基于内…

【Android】使用Termux终端的SSH服务与电脑传输文件

在Android手机上有一个Termux APP&#xff0c;可运行类似 Linux 终端的模拟器&#xff0c;记得之前有讲过用电脑远程控制手机终端命令&#xff0c;那现在&#xff0c;怎样实现电脑与手机直接传输文件呢&#xff0c;且看这篇文章。 文章目录 Termux安装功能ssh服务从远程下载从本…

深度学习入门笔记(六)线性回归模型

本节&#xff0c;我们用线性回归为例子&#xff0c;回顾一些基本概念 6.1 相关性 相关性的取值范围是-1 到 1&#xff0c;越接近 1 或者-1 代表越相关&#xff0c;越接近 0 则越不相关。相关系数大于 0 称为正相关&#xff0c;小于 0 称为负相关。 假如 A 与 B 正相关&#…

[Linux 进程控制(二)] 写时拷贝 - 进程终止

文章目录 1、写时拷贝2、进程终止2.1 进程退出场景2.1.1 退出码2.1.2 错误码错误码 vs 退出码2.1.3 代码异常终止引入 2.2 进程常见退出方法2.2.1 exit函数2.2.2 _exit函数 本片我们主要来讲进程控制&#xff0c;讲之前我们先把写时拷贝理清&#xff0c;然后再开始讲进程控制。…

VMware无法检测到插入的USB设备,虚拟机插拔USB无反应

原本正常使用的VMware虚拟机&#xff0c;在进行了重装软件后&#xff0c;发现虚拟机插拔USB设备都无法检测到&#xff0c;没有任何的反应和提示。 通过一系列的操作发现&#xff0c;在新安装了VMware workstation 软件后&#xff0c;存在一定的概率性会发生VMware虚拟机无法自…

牛客网-------------------------长方体

解题思路&#xff1a; 设棱长为x&#xff0c;y&#xff0c;z&#xff1b;假设已知面积为a&#xff0c;b&#xff0c;c 那么&#xff0c;xya&#xff1b;yzb&#xff1b;xzc&#xff1b; 一式除二式得x/za/b x(a/b)*z 联立xzc 代入得&#xff08;a/b)z^2c z^2c*b/a z根号下&…