技术标签: Vue 父子组件间的通信
前言 在 Vue 项目中父子组件的通信是非常常见的,最近做项目的时候发现对这方面的知识还不怎么熟练,在这边做一下笔记,系统学习一下吧。
父组件传值给子组件,这个就比较常见了,直接用 props 就可以了。但是就算是 props 子组件那边也有三种写法,如下面代码所示:
父组件
子组件
// 1 简单粗暴就给个名称的情况
props:['name'],
// 2 给个名称顺便指定个类型,如果父组件传递过来的值类型不对的话就会报错
props:{
name:String
},
// 3 给个名称不仅指定了类型,还顺便送了个默认值,当父组件传个空过来或者啥都没传过来的时候就用默认值了
props: {
name: {
type: String,
default: 'xhm',
}
},
注意一下的话,如果是数组或者是对象要默认值的话,直接设置默认数组或者默认对象会报错,需要用工厂函数返回,如下:
props: {
arr:{
type:Array,
default:()=>{
return [1,2,3]
}
}
},
// 对象也是和上面一个用工厂函数
由于单向数据流的限制,我们不能直接在子组件中修改 props 的值,当我们修改的时候会报错,官方的说法是:
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
所以啊,如果你不只是想在子组件中简单的渲染父组件传过来的值的话,那么可以用下面的两种方法。
这个 prop 用来传递一个初始值;
这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:
props: ['name'],
data() {
return {
userName:this.name,
};
},
这个 prop 以一种原始的值传入且需要进行转换。
在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['name'],
computed: {
userName(){
return this.firstName + this.name
}
},
虽然我们说是要单向数据流,但是很多时候,我们在子组件改变了某些值之后,还是要反馈给父组件,让父组件做一下修改,那么这个时候就要想着子组件向父组件传值啦。有下面这么两种方式
这个基本都是用 emit 来传递了,用法直接看代码吧:
子组件
// props:['name]
// methods 里
update(){
this.$emit('update','ljy');
// 第一个参数:事件名,第二个参数:传递给事件方法的参数
}
父组件
/* template 里面的代码,监听子组件里面的 update 事件,调用父组件的 childUpdate 方法
<child :name="userName" @update="childUpdate"></child>
*/
// methods
chidlUpdate(val){
// val 参数就是子组件传递过来的数据
this.userName = val;
}
虽然这样是可以实现子组件向父组件传值,但是写多一个方法感觉很烦,所以 vue 官方高出了一个 以 update:myPropName 的模式触发事件。
,这个是啥,举个例子,我们的子组件中有一个 name
的 props,我们用下面这个形式通知父组件
this.$emit('update:name', newName)
// this.$emit('update:props中的变量名', 新的值)
然后父组件可以监听那个事件并根据需要更新一个本地的数据属性:
```<child :name="userName" @update:name="userName = $event"></child> ```这样当我们在子组件触发那个修改的方法的时候,父组件的 userName
变量就会更新为 newName
了,然后为了方便起见,官方提供了一个缩写,即 .sync
修饰符。看代码吧:
上面的代码和前面的代码是一个效果,是不是方便了很多。舒服了吧。
这个的话是针对于 对象和数组那些引用类型的数据而言的,由于这些存在浅拷贝的问题(不明白浅拷贝的看这篇文章),所以可以利用这点来实现子父组件的「同生共死」,看代码吧
// 假设 name 是一个对象或者数组
props:['name'],
return {
userName:this.name,
};
就这样?!
没错就是这么简单粗暴,由于浅拷贝的问题,我们在子组件修改 userName
的时候,从父组件传递过来的那个值也会改变的,然后就会实现 props 的「双向绑定」了。但是一般没人会这么干,因为这样会造成维护上的问题,会让人觉得咋没干啥父组件的值咋就变了,会让人头秃啊,所以除非你项目中非得要搞这么一个子父组件 props 的「同生共死」,那就这么干吧。
不知道这样的叫法对不对,反正就这样啦。总结之后又下面这几种方法
其实本来 emit 就是用于子组件向父组件通信的,上面的子组件传值给父组件其实也就是父组件监听子组件的事件,然后触发父组件的方法的,换个说法,也就是子组件调用了父组件的方法,再写一下代码吧:
子组件
// methods 里
update(){
this.$emit('update','ljy');
// 第一个参数:事件名,第二个参数:传递给事件方法的参数
}
父组件
/* template 里面的代码,监听子组件里面的 update 事件,调用父组件的 childUpdate 方法
<child :name="userName" @update="childUpdate"></child>
*/
// methods
chidlUpdate(val){
// val 参数就是子组件传递过来的数据
this.userName = val;
}
上面的代码中,从某种意义上来说,就是子组件调用了父组件的 childUpdate
方法。
这个就比较简单了,我们假设我们在父组件定义了一个 fatherMethod()
方法,然后我们子组件就可以通过下面的代码实现调用 fatherMethod()
的方法
childClick(){
this.$parent.fatherMethod();
}
props 能传递 Function 类型的数据,所以,我们通过 props 当然也是可以直接的调用父组件传递过来的方法啦。不多说,直接撸代码:
父组件
子组件
props: {
fatherMethod: {
type: Function,
default: null
}
},
methods: {
childClick() {
this.fatherMethod();
}
},
这样我们也是调用了父组件的方法啦。
这个,暂时没有遇到过这种情况,不过以备不时之需,也写一下吧。父组件调用子组件的方法的话是利用 ref 获取到子组件实例,从而调用子组件的方法,假设我们子组件有这么一个 childMethod()
方法。那么我们的父组件就可以这么来调用子组件的方法了
/* <child ref="con"></child> 子组件 */
methods: {
update() {
this.$refs.con.childMethod();
},
}
至此,关于父子组件通信的的话题就聊到这边了,如果有啥错误或者遗漏的,欢迎在下面斧正啦。
文章浏览阅读436次。Vue2项目中使用 ElementUI 的 el-select 实现下拉框多选功能_el-select 选择一个后,右边弹出下级目录
文章浏览阅读518次,点赞4次,收藏2次。C#上位机调试经验_c#上位机怎么调试
文章浏览阅读132次。Python怎么样其实 Python 已经是一个很老的编程语言了,到现在(2021年) Python 已经高龄 30 岁,比很多程序员的年龄都大。现在之所以这么流行和社区、人工智能的发展,有很大的关系。2011年1月,TIOBE编程语言排行榜公布2010年度语言为Python。TIOBE排行榜的排名标准是基于排名基于互联网热度,由热门程序员、课程和第三方厂商的数量来决定排名前后,排名使用全球各大搜索引擎来计算。在国内,Python的热度也在近几年被引爆——在百度网页数上,Python处于高位,在
文章浏览阅读1.2k次。GandCrab介绍GandCrab是由一个十分猖狂的团队研发的勒索软件病毒,2018年开始活跃,一年内勒索了将近20亿美元。2019年可谓臭名远扬的勒索软件之王:GandCrab背后的运营团队在俄语论坛中发表官方声明称,GandCrab勒索病毒将停止更新。为什么停止更新了呢?答案竟是,钱赚够了。然而这么猖狂的犯罪团伙,至今都没有被找到幕后团伙是谁。这就是GandCrab勒索软件的神奇传说。今天分享就分析个去年写的GandCrab v4.0工具。GandCrab勒索软件分析白名单目录:\Pr_ctf gandcrab
文章浏览阅读1.7w次,点赞8次,收藏36次。redis的序列化和反序列化基础概念redisFactory:redis的工厂类redisTemplate:spring 封装了 RedisTemplate 对象来进行对redis的各种操作,它支持所有的 redis 原生的 api。序列化序列化能够使java的对象在传输和存储的过程中,能够成功的传输和读取。如果redis不实现序列化的结果: 不实现序列化的话,存储的key字段会出..._redistemplate.afterpropertiesset
文章浏览阅读1.1k次。背景:今天看网课提到了斐波那契数列使用递归效率过低的问题,于是自己写代码使用递归求第100项,出去吃完早饭回来还没跑完。。。好吧,需求来了,我们来开始优化吧!1、原代码def fibonacci(n): if n == 1 or n == 2: return 1 else: return fibonacci(n - 1) + fibonacci(n - 2)2、改进两种办法,本质上都是把先前函数运行的结果存起来,下一次需要调用时候直接使用。第一种是装饰器,args[0_python利用字典改进斐波那契数列递归程序
文章浏览阅读2.7k次。树莓派常用的工具,截图工具,性能查看器,vscode等_树莓派安装软件
文章浏览阅读1.1k次。Arduino 也是是接触了下,程序挺简单的,与C语言类似。LED 小灯实验是比较基础的实验之一,上一个“Hello World!”实验里已经利用到了Arduino 自带的LED,这次我们利用其他I/O 口和外接直插LED 灯来完成这个实验,我们需要的实验 器材除了每个实验都必须的Arduino 控制器和USB 下载线以外的 其它器件如下: 红色M5 直插LED*1 220Ω直插电阻*1 面包板*..._arduino和面包板接多个灯
文章浏览阅读525次。图2展示了分组查询注意力和多头/多查询注意力的比较。适中数量的组导致插值模型的质量高于MQA,但比MHA更快,正如我们将展示的那样,这代表了一个有利的权衡。然而,更大的模型通常会按比例增加头的数量,使得多查询注意力在内存带宽和容量上都表现出更激进的削减。此外,较大的模型受到注意力的内存带宽开销相对较小,因为键值缓存随着模型维度的增加而增加,而模型的FLOPs和参数随模型维度的。此外,我们引入分组查询注意力,它是多查询注意力和多头注意力的插值,既能够在与多查询注意力相当的速度下实现接近多头注意力的质量。_gqa:谷歌提出分组查询注意力
文章浏览阅读4k次,点赞5次,收藏12次。今天和大家分享一个使用Notepad++配置C语言编译环境的方法,因为本人是一个C语言新手,一般写个小程序用文本编辑器就够用。前提: 下载mingw 或者 Cygwin 或 tdm-gcc 里面有C语言编译器,然后配置环境变量。 https://sourceforge.net/projects/mingw-w64/files/?source=navbar首先: ...
文章浏览阅读836次,点赞24次,收藏17次。本文介绍了将Excel文件转换成图片格式的五种方法,包括使用汇帮PDF转换器、Excel内置功能、屏幕截图工具、复制粘贴和另存为图片。转换前需备份文件,选择合适的图片格式和分辨率,注意第三方软件的安全性。转换后便于在不同设备和平台上查看和分享Excel数据_excel图片地址转图片
文章浏览阅读2.2k次。复制的代码,还没有试过。#include <cups/cups.h>//...int print_label( const char *text, const char *printer_name, const char *job_name ){ int jobId = 0;jobId = cupsCreateJob( CUPS_HTTP_DEFAULT,..._cups/cups.h