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对象赋初始值以及后面的任何一次赋值都使用了深拷贝(建议不要按照我这样来,深拷贝还有其他方法,这里我图方便就没用了

感谢大家的观看!!!

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

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

相关文章

OllyDbg 快捷键及常用法

keywords: debug, ollydbg 快捷键 Ctrl --> C Shift --> S Alt --> M 功能快捷键设置/取消断点F2执行到光标所在行F4步过F8步进F7运行F9暂停F12回到应用层M-F9打开文件F3重新调试C-F2打开应用程序输入表C-n寻找表达式C-g打开断点窗口M-b切换断点状态空格添加备注…

[前端]NVM管理器安装、nodejs、npm、yarn配置

NVM管理器安装、nodejs、npm、yarn配置 NVM管理器安装 nvm(Node.js version manager) 是一个命令行应用&#xff0c;可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 nvm下载地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases 1.全部…

Unity面向切面编程

一直说面向AOP&#xff08;切面&#xff09;编程&#xff0c;好久直接专门扒出理论、代码学习过。最近因为某些原因&#x1f62d;还得再学学造火箭的技术。 废话不多说&#xff0c;啥是AOP呢&#xff1f;这里我就不班门弄斧了&#xff0c;网上资料一大堆&#xff0c;解释的肯定…

mybatis中<if>条件判断带数字的字符串失效问题

文章目录 一、项目背景二、真实错误原因说明三、解决方案3.1针对纯数字的字符串值场景3.2针对单个字符的字符串值场景 四、参考文献 一、项目背景 MySQL数据库使用Mybatis查询拼接select语句中进行<if>条件拼接的时候&#xff0c;发现带数字的或者带单个字母的字符串失效…

CPU资源控制

一、CPU资源控制定义 cgroups&#xff08;control groups&#xff09;是一个非常强大的linux内核工具&#xff0c;他不仅可以限制被namespace隔离起来的资源&#xff0c; 还可以为资源设置权重、计算使用量、操控进程启停等等。 所以cgroups&#xff08;control groups&#xf…

在ubuntu20上编译bcc时遇到:Could NOT find LibDebuginfod

参考&#xff1a;https://github.com/iovisor/bcc/issues/3601 环境 Ubuntu20.04 ARM64 问题 编译bcc时报下面的错误&#xff1a; -- Found BISON: /usr/bin/bison (found version "3.5.1") -- Found FLEX: /usr/bin/flex (found version "2.6.4") …

Netty学习——实战篇5 Netty 心跳监测/WebSocket长连接编程 备份

1 心跳监测 MyServer.java public class MyServer {public static void main(String[] args) {NioEventLoopGroup bossGroup new NioEventLoopGroup(1);NioEventLoopGroup workerGroup new NioEventLoopGroup();try {ServerBootstrap serverBootstrap new ServerBootstrap…

leetcode145--二叉树的后序遍历

1. 题意 求后序遍历 2. 题解 2.1 递归 class Solution { public:void addPost(TreeNode *root, vector<int> &res) {if ( nullptr root)return ;addPost(root->left, res);addPost(root->right, res);res.emplace_back( root->val );}vector<int>…

设计前后端系统以处理长时间运行的计算任务并提供缓存支持

后端设计 1. 任务队列 创建一个任务队列来存储提交的计算任务。 Component public class TaskQueue {private final Queue<CalculationTask> queue new LinkedList<>();public synchronized void addTask(CalculationTask task) {queue.add(task);}public sync…

C++ 全量枚举

在C中&#xff0c;全量枚举通常指的是为一个类型的所有可能值创建一个枚举。这样可以使代码更具可读性&#xff0c;特别是当你需要处理有限的、固定的值集合时。 下面是一个简单的例子&#xff0c;展示了如何定义和使用枚举&#xff1a; #include <iostream>// 定义枚举…

lvresize与lvextend扩容逻辑卷的区别

这两条命令都是用来扩展逻辑卷&#xff08;Logical Volume&#xff09;的命令&#xff0c;但是有一些区别&#xff1a; 1. lvresize命令&#xff1a; - lvresize命令是用来调整逻辑卷的大小的&#xff0c;可以缩小或扩大逻辑卷的大小。 - 在使用lvresize命令时&#xff0c;需…

20240425 每日一题:2739. 总行驶距离

题目简介 卡车有两个油箱。给你两个整数&#xff0c;mainTank 表示主油箱中的燃料&#xff08;以升为单位&#xff09;&#xff0c;additionalTank 表示副油箱中的燃料&#xff08;以升为单位&#xff09;。 该卡车每耗费 1 升燃料都可以行驶 10 km。每当主油箱使用了 5 升燃…

学习Docker笔记

在23号刚刚学完新版本的docker还想说回去继续学习老版本的springcloud课程里面的docker 结果一看黑马首页新版本课程出了&#xff0c;绷不住了。以下是我学习新版本docker的笔记&#xff0c;记录了我学习过程遇到的各种bug和解决&#xff0c;也参考了黑马老师的笔记&#xff1a…

TDengine高可用探讨

提到数据库&#xff0c;不可避免的要考虑高可用HA&#xff08;High Availability&#xff09;。但是很多人对高可用的理解并不是很透彻。 要搞清高可用需要回答以下几个问题&#xff1a; 什么是高可用&#xff1f;为什么需要高可用&#xff1f;高可用需要达到什么样的目标&am…

Unity射线实现碰撞检测(不需要rigbody组件)

使用physic.CapsulCast&#xff08;&#xff09;&#xff1b; 前面3个参数生成一个胶囊体&#xff0c; 向着发射方向&#xff0c;发射出一串的胶囊&#xff08;没有最大距离&#xff09; 有最大距离&#xff0c;可以节约性能开销。 physic.CapsulCast&#xff08;&#xff0…

记录一次使用springboot 3 用gradle脚本的踩坑记录

问题1 . 下载插件或者gradle以及gradle plus有问题 报错&#xff1a;Could not resolve org.springframework.boot:spring-boot-gradle-plugin:3.3.0-RC 解决方法&#xff1a;使用如下配置 settings.gradle的 pluginManagement下 repositories是插件的依赖或者插件的下载地址…

easypoi 导出增加自增序列

要求&#xff1a;使用easypoi导出Excel的时候&#xff0c;要求增加”序号“列&#xff0c;从1开始增加。这列与业务数据无关&#xff0c;只是展示用&#xff0c;便于定位。如下图所示 实现方式&#xff1a;Java对象新增一列&#xff0c;注意name "序号", format &…

测试工程师常见面试题及答案

什么是软件测试生命周期&#xff08;STLC&#xff09;? STLC是一个特定的阶段序列&#xff0c;用于测试软件或应用程序。它包括以下阶段&#xff1a; 需求分析报告计划测试设计测试环境设置测试执行测试闭环或评估 解释黑盒测试和白盒测试的区别 黑盒测试是一种测试方法&#…

Linux-缓冲区(简单理解)

1. 缓冲区是什么 缓冲区就是一段内存空间。 2. 为什么要有缓冲区 IO写入有两种&#xff1a; 写透模式&#xff08;WT&#xff09; 成本高&#xff0c;效率低写回模式&#xff08;WB&#xff09; 成本低&#xff0c;效率高 写透模式&#xff1a;每次的文件写入都要立即刷新…

【006期】用Processing写一个根据音乐变化的黑白格游戏

黑白格游戏 简述准备工作游戏设计实现代码注意事项优化二次优化 简述 为了创建一个简单的根据音乐变化的黑白格游戏&#xff0c;我们将利用Processing的简洁性和直观操作来实现。游戏的核心思想是&#xff1a;屏幕上呈现多个黑白格&#xff0c;随着音乐的播放&#xff0c;格子…