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:()=>{
return [1,2,3]
}
}
},
// 对象也是和上面一个用工厂函数
1.2 子组件使用父组件的值
由于单向数据流的限制,我们不能直接在子组件中修改 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
}
},
2 子组件传值给父组件
虽然我们说是要单向数据流,但是很多时候,我们在子组件改变了某些值之后,还是要反馈给父组件,让父组件做一下修改,那么这个时候就要想着子组件向父组件传值啦。有下面这么两种方式
2.1 emit 方法
这个基本都是用 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 修饰符。看代码吧:
```<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 方法
<child :name="userName" @update="childUpdate"></child>
*/
// 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() 方法。那么我们的父组件就可以这么来调用子组件的方法了
/* <child ref="con"></child> 子组件 */
methods: {
update() {
this.$refs.con.childMethod();
},
}
至此,关于父子组件通信的的话题就聊到这边了,如果有啥错误或者遗漏的,欢迎在下面斧正啦。
原文地址:https://segmentfault.com/a/1190000017346476
Vue 父子组件间的通信的更多相关文章
- Vue父子组件间的通信
父组件通过 props 向下传递数据给子组件,子组件通过 events 向上给父组件发送消息. 父组件: <div> <div style="background:#344 ...
- 第四节:Vue表单标签和组件的基本用法,父子组件间的通信
vue表单标签和组件的基本用法,父子组件间的通信,直接看例子吧. <!DOCTYPE html> <html> <head> <meta charset=&q ...
- vue组件定义方式,vue父子组件间的传值
vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...
- 【转】vue父子组件之间的通信
vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...
- React中父子组件间的通信问题
1.https://blog.csdn.net/sinat_17775997/article/details/59103173 (React中父子组件间的通信问题)
- vue:父子组件间通信,父组件调用子组件方法进行校验子组件的表单
参考: ElementUI多个子组件表单的校验管理:https://www.jianshu.com/p/541d8b18cf95 Vue 子组件调用父组件方法总结:https://juejin.im/ ...
- vue父子组件之间的通信
利用props在子组件接受父组件传过来的值1.父组件parentComp.vue <template> <childComp :fromParentToChild="fro ...
- vue -- 父子组件间的事件触发
1.父组件触发子组件事件 Parent.vue <child ref="child"></child> <div @click="fn&qu ...
- vue——父子组件间传值
(1)父组件给子组件传值(商品详情页): 根据订单类型,判断显示立即购买/立即拼单: 通过props来传递参数 父组件(商品详情页) 父组件调用子组件,在子组件的标签中,通过:数据名称=”数据”的形式 ...
随机推荐
- JavaScript进阶 - 第8章 浏览器对象
第8章 浏览器对象 8-1 window对象 window对象是BOM的核心,window对象指当前的浏览器窗口. window对象方法:
- Java NIO 必知必会(Example)
管道流: Java NIO 管道是2个线程之间的单向数据连接.Pipe有一个source通道和一个sink通道.数据会被写到sink通道,从source通道读取. package base.nio.t ...
- Educational Codeforces Round 66 (Rated for Div. 2) A. From Hero to Zero
链接:https://codeforces.com/contest/1175/problem/A 题意: You are given an integer nn and an integer kk. ...
- Net Core微服务
Net Core微服务 http://www.cnblogs.com/qhbm/category/1235971.html 开发工具:VS2017 .Net Core 2.1 什么是微服务? 单体结构 ...
- zabbix agent 配置
http://blog.csdn.net/z644041867/article/details/76618644 https://www.cnblogs.com/miclesvic/p/6144924 ...
- MapReduce基本流程与设计思想初步
1.MapReduce是什么? MapReduce是一种编程模型,用于大规模数据集的并行运算.它借用了函数式的编程概念,是Google发明的一种数据处理模型. 主要思想为:Map(映射)和Reduce ...
- 缓存List并写入文件持久化
LIfe is half spent before we know what is it. 缓存List并写入文件持久化 需要缓存一个List集合,比如缓存一个输入框中用户之前输入过的内容,下次当用户 ...
- 数据结构-List接口-LinkedList类-Set接口-HashSet类-Collection总结
一.数据结构:4种--<需补充> 1.堆栈结构: 特点:LIFO(后进先出);栈的入口/出口都在顶端位置;压栈就是存元素/弹栈就是取元素; 代表类:Stack; 其 ...
- C++析构函数造成Debug Assertion Failed的问题
昨天写了两个程序,均出现了析构函数造成Debug Assertion Failed的问题,由于是初学c++怎么想也想不通问题出在哪里.今天早上经人指点终于明白问题所在了.下面贴出代码和问题解析:(以下 ...
- 【extjs6学习笔记】1.6 初始:本地化
app.json中修改