Vue 父子组件间的通信_this.$emit('update:names-程序员宅基地

技术标签: Vue 父子组件间的通信  

前言 在 Vue 项目中父子组件的通信是非常常见的,最近做项目的时候发现对这方面的知识还不怎么熟练,在这边做一下笔记,系统学习一下吧。

1 父组件传值给子组件

1.1 传值写法

父组件传值给子组件,这个就比较常见了,直接用 props 就可以了。但是就算是 props 子组件那边也有三种写法,如下面代码所示:
父组件

```<!-- 两种情况 --> <!--静态传值--> <child name="xhm"></child> <!--动态传值--> <child :name="userName"></child> ```

子组件


// 1 简单粗暴就给个名称的情况
props:['name'],
// 2 给个名称顺便指定个类型,如果父组件传递过来的值类型不对的话就会报错
props:{
    name:String
},
// 3 给个名称不仅指定了类型,还顺便送了个默认值,当父组件传个空过来或者啥都没传过来的时候就用默认值了
props: {
  name: {
    type: String,
    default: 'xhm',
  }
},

注意一下的话,如果是数组或者是对象要默认值的话,直接设置默认数组或者默认对象会报错,需要用工厂函数返回,如下:


props: {
  arr:{
    type:Array,
    default:()=&gt;{
       return [1,2,3]
    }
  }
},
// 对象也是和上面一个用工厂函数

1.2 子组件使用父组件的值

由于单向数据流的限制,我们不能直接在子组件中修改 props 的值,当我们修改的时候会报错,官方的说法是:

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

所以啊,如果你不只是想在子组件中简单的渲染父组件传过来的值的话,那么可以用下面的两种方法。

  1. 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:

props: ['name'],
data() {
  return {
    userName:this.name,
  };
},
  1. 这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

props: ['name'],
computed: {
  userName(){
    return this.firstName + this.name
  }
},

2 子组件传值给父组件

虽然我们说是要单向数据流,但是很多时候,我们在子组件改变了某些值之后,还是要反馈给父组件,让父组件做一下修改,那么这个时候就要想着子组件向父组件传值啦。有下面这么两种方式

2.1 emit 方法

这个基本都是用 emit 来传递了,用法直接看代码吧:
子组件


// props:['name]

// methods 里
update(){
  this.$emit('update','ljy');
  // 第一个参数:事件名,第二个参数:传递给事件方法的参数
}

父组件



/* template 里面的代码,监听子组件里面的 update 事件,调用父组件的 childUpdate 方法

 &lt;child :name="userName" @update="childUpdate"&gt;&lt;/child&gt;

*/
// 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 修饰符。看代码吧:

```<child :name.sync="userName"></child> ```

上面的代码和前面的代码是一个效果,是不是方便了很多。舒服了吧。

2.2 利用浅拷贝(不推荐)

这个的话是针对于 对象和数组那些引用类型的数据而言的,由于这些存在浅拷贝的问题(不明白浅拷贝的看这篇文章),所以可以利用这点来实现子父组件的「同生共死」,看代码吧


// 假设 name 是一个对象或者数组
props:['name'],
return {
  userName:this.name,
};

就这样?!

没错就是这么简单粗暴,由于浅拷贝的问题,我们在子组件修改 userName 的时候,从父组件传递过来的那个值也会改变的,然后就会实现 props 的「双向绑定」了。但是一般没人会这么干,因为这样会造成维护上的问题,会让人觉得咋没干啥父组件的值咋就变了,会让人头秃啊,所以除非你项目中非得要搞这么一个子父组件 props 的「同生共死」,那就这么干吧。

3 子组件调用父组件的方法

不知道这样的叫法对不对,反正就这样啦。总结之后又下面这几种方法

3.1 emit

其实本来 emit 就是用于子组件向父组件通信的,上面的子组件传值给父组件其实也就是父组件监听子组件的事件,然后触发父组件的方法的,换个说法,也就是子组件调用了父组件的方法,再写一下代码吧:

子组件


// methods 里
update(){
  this.$emit('update','ljy');
  // 第一个参数:事件名,第二个参数:传递给事件方法的参数
}

父组件



/* template 里面的代码,监听子组件里面的 update 事件,调用父组件的 childUpdate 方法

 &lt;child :name="userName" @update="childUpdate"&gt;&lt;/child&gt;

*/
// methods
chidlUpdate(val){
  // val 参数就是子组件传递过来的数据
  this.userName = val;
}

上面的代码中,从某种意义上来说,就是子组件调用了父组件的 childUpdate 方法。

3.2 this.$paarent.event

这个就比较简单了,我们假设我们在父组件定义了一个 fatherMethod() 方法,然后我们子组件就可以通过下面的代码实现调用 fatherMethod() 的方法


childClick(){
  this.$parent.fatherMethod();
}

3.3 props

props 能传递 Function 类型的数据,所以,我们通过 props 当然也是可以直接的调用父组件传递过来的方法啦。不多说,直接撸代码:
父组件

```<!-- 假设父组件里定义了一个 fatherMethod() 方法 --> <child :fatherMethod="fatherMethod"></child> ```

子组件


props: {
  fatherMethod: {
    type: Function,
    default: null
  }
},
methods: {
  childClick() {
    this.fatherMethod();
  }
},

这样我们也是调用了父组件的方法啦。

4 父组件调用子组件的方法

这个,暂时没有遇到过这种情况,不过以备不时之需,也写一下吧。父组件调用子组件的方法的话是利用 ref 获取到子组件实例,从而调用子组件的方法,假设我们子组件有这么一个 childMethod() 方法。那么我们的父组件就可以这么来调用子组件的方法了


/* &lt;child ref="con"&gt;&lt;/child&gt; 子组件 */

methods: {
  update() {
    this.$refs.con.childMethod();
  },
}

至此,关于父子组件通信的的话题就聊到这边了,如果有啥错误或者遗漏的,欢迎在下面斧正啦。

原文地址:https://segmentfault.com/a/1190000017346476

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/w178191520/article/details/84989878

智能推荐

dojo中的dgrid使用时注意事项_fly/dgrid/selector用法-程序员宅基地

文章浏览阅读3.5k次。最近在使用dojo的dgrid控件,遇到的问题还是蛮多的,有些细节不注意的话,很难符合你的要求,而且找个解决方案都没有。求人不如求己,经过我认真地查看dgrid的demo,主要是这个地址是:http://dgrid.io/js/dgrid/demos/laboratory/选择左边的一些控件,然后查看右边表格的效果,总体来说做的还可以。ok,进入正题。这个是我想达到的效果:_fly/dgrid/selector用法

能力更强,医疗单据识别+医疗知识库校验_针对医疗表格识别进行优化-程序员宅基地

文章浏览阅读183次。此次更新升级,包括门诊住院发票识别、医疗费用清单识别、出院小结识别均增加了医疗知识库功能,除了单纯的OCR识别,用户可以选择对识别结果进行医疗知识库匹配校验。在线体验门诊住院发票、医疗费用清单识别时,可以选择相应的省市医保目录进行核对;在线体验出院小结识别,则可以选择匹配相应的ICD-10编码及名称。..._针对医疗表格识别进行优化

在线考试系统(源码+mysql+文档)-程序员宅基地

文章浏览阅读573次,点赞9次,收藏7次。后端SSM框架结合了Spring的依赖注入和事务管理、SpringMVC的模型-视图-控制器架构以及MyBatis的数据持久化功能,为后端开发提供全面的支持。在线考试系统app03182的意义不仅仅在于其技术层面的突破。更重要的是,它对教育公平性的提升、资源优化配置以及学习效率的提高具有不可估量的影响。它的出现,标志着传统考试方式的一大跨越,使得教与学的互动不再受时间和空间的限制,极大地拓宽了教育的边界。它通过提供创新的考试方式,促进了教育评价体系的完善,对实现教育现代化、促进社会进步具有深远的意义。

google play 上架更改成自己生成的应用签名实践_google play 签名生成-程序员宅基地

文章浏览阅读377次,点赞2次,收藏2次。google play 上架卡关在更改应用签名上。不想用google生成 签名,自己用keytool生成的密钥来用。为了顺利,其实可以放弃开发时自己测试用打包的密钥,重新生成新的密钥来配合本文章,会有意想不到的的顺利——可能是玄学!_google play 签名生成

ubuntu 安装 python3.8_ubuntu python3.8安装不了-程序员宅基地

文章浏览阅读955次。Windows 10 里面的 linux子系统,里面有 python2.x 和 python3.6。想要升级到 python3.8,却不成功。网上请教了高人,说要先升级 ubuntu。于是,执行:apt-get update 升级 ubuntu;然后再执行:apt-get install python3.8成功开始安装了。另外一个概念:python 的多个版本,可以在同一个 linux 底下共存。我的 linux 底下输入:python 进入的是 python2..._ubuntu python3.8安装不了

iOS根据字符串计算UITextView高度_ios uitextview 字符串高度-程序员宅基地

文章浏览阅读3.3k次。iOS计算字符串高度,有需要的朋友可以参考下。方法一:ios7.0之前适用/** @method 获取指定宽度width,字体大小fontSize,字符串value的高度 @param value 待计算的字符串 @param fontSize 字体的大小 @param Width 限制字符串显示区域的宽度 @result float 返回的高度 */- (float_ios uitextview 字符串高度

随便推点

Android应用AsyncTask处理机制详解及源码分析-程序员宅基地

文章浏览阅读625次。工匠若水 http://blog.csdn.net/yanbober1 背景当使用线程和Handler组合实现异步处理时,当每次执行耗时操作都创建一条新线程进行处理,性能开销会比较大。为了提高性能我们使用AsyncTask实现异步处理(其实也是线程和handler组合实现),因为其内部使用了java提供的线程池技术,有效的降低了线程创建数量及限定了同时运行的线程数,还有一些

零基础学大数据开发,Spark 学习资源分享-程序员宅基地

文章浏览阅读225次。本系列是基于目前最新的 spark 1.6.0 系列开始的,spark 目前的更新速度很快,记录一下版本好还是必要的。 来源:segmentfault1. 书籍Learning Spark Mastering Apache Spark2. 网站official site user mailing list spark channel on youtube ...

CISCO WLC的配置备份与导入_思科wlc配置b备份-程序员宅基地

文章浏览阅读1w次。导出配置: 导入配置 原有配置 删除 导入配置,设备会重启_思科wlc配置b备份

云计算——常见集群策略_虚拟机 dpm-程序员宅基地

文章浏览阅读3.7k次,点赞65次,收藏70次。本章将会讲解云计算中常见的集群策略,了解什么是集群。_虚拟机 dpm

手动脱壳[HZNUCTF 2023 final]signin-程序员宅基地

文章浏览阅读1.3k次,点赞42次,收藏20次。手动脱壳时时刻关注esp寄存器,来找到正真程序的入口。

Qt获取控件位置,坐标总结_qt 按钮位置坐标-程序员宅基地

文章浏览阅读8.9k次。总结的结果是:QMouseEvent中两类坐标系统,一类是窗口坐标,一类是显示器坐标。总结一:经过试验,QMouseEvent::globalPos() 和 QCursor::pos()效果一样,但是Qt帮助文档说不一样,可是我获得值确实相同的。QCursor::pos() == QMouseEvent::globalPos() 都是全局坐标;总结_qt 按钮位置坐标

推荐文章

热门文章

相关标签