VUE父组件向子组件传递值

2024-04-25 13:12

本文主要是介绍VUE父组件向子组件传递值,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

创作灵感

最近在写一个项目时,遇到了这样的一个需求。我封装了一个组件,这个组件需要被以下两个地方使用,一个是搜索用户时用到,一个是修改用户信息时需要用到。其中,在搜索用户时,可以根据姓名或者账号进行搜索。根据账号一次只能搜索出一个用户,根据姓名可以一次性搜出许多名字包含该内容的用户,如下图:

按名称搜索示意图

然而,在更改用户信息界面使用该组件时,我们不希望用户能通过姓名来查询,因为我们是一个一个的修改用户信息的,如果通过姓名查询会查询出多个数据。因此,我们需要在更新用户信息界面使用该组件是禁止选择姓名选项,如下:

 禁止按名称搜索示意图

效果实现

要想实现上面的效果,大致思路就是父组件在使用子组件时,传递一个参数,根据这个参数选择是否禁用。这就需要用到父组件向子组件传递值的知识了。父组件向子组件传值最简单的就是props了,如果有多重传递,则需要用到别的方法,大家可以去了解一下,这里我使用的是props。

下面为子组件与父组件的代码实现:

<template><div class="mt-4"><el-inputv-model="content"style="max-width: 600px"placeholder="请输入用户信息"class="input-with-select"><template #prepend><el-select v-model="select" placeholder="账号" style="width: 115px"><el-option :disabled="noSelect==1" label="账号" value="1" /><el-option :disabled="noSelect==2" label="姓名" value="2" /></el-select></template><template #append><el-button @click="search" icon="Search" /></template></el-input></div>
</template><style scoped lang="scss"></style><script lang="ts">
import { defineComponent,reactive, ref, toRaw } from 'vue'
import API from '@/untils/axios'
import { ElMessage } from 'element-plus'export default defineComponent({props:['noSelect'],emits:["returnResults"],name:"searchComponent",setup(){var select=ref("1")var content=ref("")var users=reactive({//返回的前十位用户信息data:[]})var total=ref(0)return{select,users,total,//总的记录数content}},methods:{search(){if(this.content==""){ElMessage({message:"搜索值为空",type:"warning"})return}API.get("admin/searchUsers",{params:{type:this.select,content:this.content                }}).then((res:any|undefined)=>{if(res==undefined){return}if(res.data.users.length==0){ElMessage({message:"搜索为空",})} else {ElMessage({message:"搜索成功",type:"success"})}this.users.data=res.data.usersthis.total=res.data.totalvar result={users:toRaw(this.users.data),//搜索出来的前10位信息total:this.total,content:this.content}this.$emit("returnResults",result)})}}
})
</script>

大家主要看到的是props,里面就包含了父组件传来的'noSelect',子组件根据传来的值来禁止需要禁止的选项

父组件传递值:

<template><div><searchComponent :noSelect="2" class="searchComponent"/><el-divider /></div>
</template><script lang="ts">
import { defineComponent } from 'vue'
import searchComponent from "@/components/searchComponent.vue"export default defineComponent({components:{searchComponent}
})
</script><style scoped lang="scss">
.searchComponent{margin: 5vh;
}
</style>

在这里,我在使用子组件时,向其传递了'noSelect'值为2,意味着禁止了姓名选项。子组件拿到值后就可以根据拿到的值来禁止对应的选项卡了。

子向父动态的取得值并且能够改变该值

其实上面的这个标题并不完全正确,因为一般情况下,我们并不希望子组件可以直接修改父组件的值,如果真的有类似的需求,应当如何完成呢?答案是子组件复制父组件所传递的值,而后修改复制后的值就可以了。下面向大家展示一下具体的应用场景:

在上面的这个场景内,我们需要用到两个子组件,搜索的子组件与展示个人信息的子组件。其中、展示个人信息的子组件用到了两次,一次为仅供展示的,一个是可供编辑的,这样在修改个人信息时,就可以知道自己修改了哪些部分。但是需要注意的是,一开始个人展示组件里面的信息是空的,我们如何使其在拿到父组件的值后能相应的更改呢?(由于我在子组件内可能需要改变父组件传递的值,所以我们不能直接使用父组件的响应式来完成这个功能)。

这时我们就需要监听父组件传递的值,如果其发生了改变,我们就改变子组件本地备份的数据,就能做到——既可以编辑父组件传递的值(实际上为其对应的深拷贝对象)、又能在父组件重新给值时响应式的改变子组件的内容了。具体代码如下:

<script lang="ts">
import { defineComponent, reactive,watch } from 'vue'export default defineComponent({props:['readOnly','user'],//readOnly(是否设置为只读)setup(props){watch(props.user,(newUser)=>{//监听父组件传递值发生改变后,将子组件的值一起改变localUser.data=newUser.data.data})var localUser:any=reactive({//拿到父组件传递过来的初始值对象,并使用reactive对其进行响应式监听data:props.user.data.data})return{localUser}},
})
</script>

子组件的js部分

上述js中,我在setup()内定义了一个本地的localUser,并且将其定义为了一个响应式的对象。其内部的值取自父组件传来的user对象,子组件可以通过编辑localUser对象,令用户感觉他们在编辑user一样。同时,此时如果还想父组件的user发生改变,子组件同时改变时,必须使用watch进行监听了。有人或许会说,我们把父组件的user对象设置为一个响应式对象不就行了?然而,由于子组件展示的是localUser,不是父组件的user,在子组件内没有触发localUser对象的值发生改变是不会令其内容发生变动的。所以必须使用一个监听器来监听父组件的值发生变动时,及时的将变动的新值赋值给子组件的本地user

其他问题

在介绍完这些后,最后向大家再介绍一个易错点,那就是浅拷贝问题。因为我这里的展示面板使用了两次,一个是仅供参考的,一个是可供编辑的。但如果在向两个子组件传值时使用的是浅拷贝,会导致在编辑面板修改时,展示面板也会被修改。解决办法就是在编辑面板传值时使用深拷贝。具体的大家可以翻看我之前的文章,下面向大家展示一下我的解决方法:

<script lang="ts">
import { defineComponent, reactive } from 'vue'
import searchComponent from "@/components/searchComponent.vue"
import userDetail from '@/components/userDetail.vue'export default defineComponent({components:{searchComponent,userDetail},setup(){var user:{//初始对象,无需响应式data:{id:number,name:string,sex:string,account:string,type:string,avatar_url:string,email:string,myselfIntroduce:string,isIdentification:number,}}={data:{id:0,name:"",sex:"",account:"",type:"",avatar_url:"",email:"",myselfIntroduce:"",isIdentification:-1}}var readUser=reactive({//只读对象,需要响应式的传递至子组件data:user})var writeUser=reactive({//可读写对象,需要响应式的传递至子组件data:JSON.parse(JSON.stringify(user))//简单深度拷贝,防止修改该对象时影响到别的对象})return{user,readUser,writeUser,}},methods:{getResult(e:any){if(e.total==0){return}this.readUser.data.data=e.users[0]this.writeUser.data.data=JSON.parse(JSON.stringify(e.users[0]))//对于有修改的部分传值使用深拷贝}}
})
</script>

上面的就是我父组件的js内容,其中,在对writerUser对象赋初始值以及后面的任何一次赋值都使用了深拷贝(建议不要按照我这样来,深拷贝还有其他方法,这里我图方便就没用了

感谢大家的观看!!!

这篇关于VUE父组件向子组件传递值的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/934779

相关文章

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

CSS place-items: center解析与用法详解

《CSSplace-items:center解析与用法详解》place-items:center;是一个强大的CSS简写属性,用于同时控制网格(Grid)和弹性盒(Flexbox)... place-items: center; 是一个强大的 css 简写属性,用于同时控制 网格(Grid) 和 弹性盒(F

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求