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

简介

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的初始值,如果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没有赋初始值,在子组件中接收到的会是undefined。这是因为 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.mfbz.cn/a/372504.html

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

相关文章

代码生成器(新):mybatis-plus-generator使用指南

代码生成器&#xff08;新&#xff09;官网 后端代码&#xff1a;点击查看 LearnElementUiAndSpringBoot 提醒&#xff1a;LearnElementUiAndSpringBoot下载完后&#xff0c;在运行调试 Main.java里的main方法之前&#xff0c;除了utils包和Main.java文件&#xff0c;其他包需…

机器学习逻辑回归模型训练与超参数调优 ##3

文章目录 [TOC]基于Kaggle电信用户流失案例数据&#xff08;可在官网进行下载&#xff09;逻辑回归模型训练逻辑回归的超参数调优 基于Kaggle电信用户流失案例数据&#xff08;可在官网进行下载&#xff09; 数据预处理部分可见&#xff1a; 机器学习数据预处理方法&#xff0…

共享网盘系统PHP源码

新V5.0版本&#xff0c;支持上传视频、支持视频播放、支持共享&#xff0c;也可以自己用。 可以自动生成视频外链&#xff0c;下载地址&#xff0c;播放器代码&#xff0c;html代码&#xff0c;ubb代码等等。 使用方法&#xff1a; 源码上传到服务器&#xff0c;打开网站根据…

【自定义序列化器】⭐️通过继承JsonSerializer和实现WebMvcConfigurer类完成自定义序列化

目录 前言 解决方案 具体实现 一、自定义序列化器 二、两种方式指定作用域 1、注解 JsonSerialize() 2、实现自定义全局配置 WebMvcConfigurer 三、拓展 WebMvcConfigurer接口 章末 前言 小伙伴们大家好&#xff0c;上次做了自定义对象属性拷贝&#x…

LLM之RAG实战(二十三)| LlamaIndex高级检索(二):父文档检索

在上一篇文章中&#xff0c;我们介绍了基本RAG的构建&#xff0c;也探讨了RAG管道中从小到大检索技术的两种主要技术&#xff1a;父文档检索和句子窗口检索。 在本文&#xff0c;我们将深入探讨一下从小到大检索技术中的父文档检索。 一、块引用&#xff1a;较小的子块引用较大…

css浮动

CSS浮动 1. 浮动的简介 在最初&#xff0c;浮动是用来实现文字环绕图片效果的&#xff0c;现在浮动是主流的页面布局方式之一。 2. 元素浮动后的特点 脱离文档流。不管浮动前是什么元素&#xff0c;浮动后&#xff1a;默认宽与高都是被内容撑开&#xff08;尽可能小&#x…

AI专题:冬渐去、春将来,待看,AI 开花,数据挂果,可控链潮起

今天分享的是AI 系列深度研究报告&#xff1a;《AI专题&#xff1a;冬渐去、春将来&#xff0c;待看&#xff0c;AI 开花&#xff0c;数据挂果&#xff0c;可控链潮起》。 &#xff08;报告出品方&#xff1a;AVIC&#xff09; 报告共计&#xff1a;36页 行业概览:2023年呈稳…

哪种安全数据交换系统,可以满足信创环境要求?

安全数据交换系统是一种专门设计用于在不同网络环境之间安全传输数据的技术解决方案。这类系统确保数据在传输过程中的完整性、机密性和可用性&#xff0c;同时遵守相关的数据保护法规和行业标准。 使用安全数据交换系统的原因主要包括以下几点&#xff1a; 1、数据保护&#…

光隔离探头

一、前言。 光隔离探头的CMRR比高压差分探头要高很多,在一些共模电压较高的测量领域用的比较多,如:开关电源、逆变器等。但是市面上介绍光隔离探头的方案比较少,这里简要说明一下我的个人想法。 二、数字光和模拟光。 数字光就是通信上常用的光模块,传的是数字信号,带…

【学网络安全】kali linux入门及常用简单工具介绍(附工具包)

前言 相信很多同学了解到和学习网络安全的时候都听过kali系统&#xff0c;大家都称之为黑客最喜爱的系统&#xff0c;那么什么是kali&#xff0c;初学者用kali能做些什么&#xff0c;我将在本文中做简单的介绍 一、kali linux是什么&#xff1f; Kali Linux 是专门用于渗透测…

linux服务器springboot或tomcat项目启动,进行jvm参数调优设置

简介 在实验环境或生产环境中&#xff0c;往往一台linux服务器需要添加启动n个项目&#xff0c;但是项目启动占用的jvm内存默认值基本上都是很大的&#xff0c;800m到2G都有&#xff0c;这样很容易将服务器的内存吃垮&#xff0c;从而导致系统强制oom&#xff08;内存泄露&…

(7)医学图像配准综述:SimpleITK + SimpleElastix + Elastix + ITKElastix + PyElastix

文章目录 前言一、常见的图像配准工具1.0、ITK VTK —— 科学界最大与最早的开源免费项目之一1.1、ITK系列&#xff1a;ITK SimpleITK SimpleElastix1.2、Elastix系列&#xff1a;Elastix ITKElastix PyElastix 二、图像配准2.1、SimpleITK图像配准2.2、SimpleElastix图像…

ROS从入门到精通4-1:Docker安装与常用命令总结

目录 0 专栏介绍1 Docker与机器人应用2 Docker安装步骤3 Docker常用命令3.1 创建与启动容器3.2 暂停与删除容器3.3 容器文件拷贝3.4 构建镜像与上下文 0 专栏介绍 本专栏旨在通过对ROS的系统学习&#xff0c;掌握ROS底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS进…

(2021|ICLR,LoRA,秩分解矩阵,更少的可训练参数)LoRA:大语言模型的低秩自适应

LoRA: Low-Rank Adaptation of Large Language Models 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. 问题陈述 3. 现有的解决方案不够好吗&#xff1f; 4. 我们的方法 …

stack和queue及优先级队列和适配器(包括deque)的介绍

stack stack的介绍 stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并提供一组…

Coil:Android上基于Kotlin协程的超级图片加载库

Coil&#xff1a;Android上基于Kotlin协程的超级图片加载库 1. coil简介 在当今移动应用程序的世界中&#xff0c;图片加载是一个不可或缺的功能。为了让应用程序能够高效地加载和显示图片&#xff0c;开发人员需要依赖于强大的图片加载库。而今天&#xff0c;我将向大家介绍…

小程序插件测试

1、下载微信小程序开发者工具&#xff0c;下载地址&#xff1a; 微信开发者工具下载地址与更新日志 | 微信开放文档 选择稳定版下载&#xff1a; 2、下载并解压测试项目&#xff08;此处根据公司的项目来&#xff0c;可问开发要&#xff09; 3、导入解压后的文件夹&#xff…

Flink cdc3.0动态变更表结构——源码解析

文章目录 前言源码解析1. 接收schema变更事件2. 发起schema变更请求3. schema变更请求具体处理4. 广播刷新事件并阻塞5. 处理FlushEvent6. 修改sink端schema 结尾 前言 上一篇Flink cdc3.0同步实例 介绍了最新的一些功能和问题&#xff0c;本篇来看下新功能之一的动态变更表结…

通过Navicat for MySQL排查sql语句错误

开发的软件用到MySQL数据库&#xff0c;但在进行某个sql操作时执行失败了&#xff1a; 我们可以用Navicat for MySQL来排查sql语句是否存在语法错误等问题。将该sql语句复制 打开Navicat for MySQL&#xff0c;连接该软件所用到的MySQL数据库&#xff0c;点击“新建查询”。将刚…

AI嵌入式K210项目(26)-二维码识别

文章目录 前言一、什么是二维码&#xff1f;二、实验准备三、实验过程四、API接口总结 前言 本章介绍基于机器视觉实现二维码识别&#xff0c;主要包含两个过程&#xff0c;首先检测图像中是否有二维码&#xff0c;如果有则框出并打印二维码信息&#xff1b; 一、什么是二维码…
最新文章