前言 在 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

Vue 父子组件间的通信的更多相关文章

  1. Vue父子组件间的通信

    父组件通过 props 向下传递数据给子组件,子组件通过 events 向上给父组件发送消息. 父组件: <div> <div style="background:#344 ...

  2. 第四节:Vue表单标签和组件的基本用法,父子组件间的通信

    vue表单标签和组件的基本用法,父子组件间的通信,直接看例子吧. <!DOCTYPE html> <html> <head> <meta charset=&q ...

  3. vue组件定义方式,vue父子组件间的传值

    vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...

  4. 【转】vue父子组件之间的通信

    vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...

  5. React中父子组件间的通信问题

    1.https://blog.csdn.net/sinat_17775997/article/details/59103173 (React中父子组件间的通信问题)

  6. vue:父子组件间通信,父组件调用子组件方法进行校验子组件的表单

    参考: ElementUI多个子组件表单的校验管理:https://www.jianshu.com/p/541d8b18cf95 Vue 子组件调用父组件方法总结:https://juejin.im/ ...

  7. vue父子组件之间的通信

    利用props在子组件接受父组件传过来的值1.父组件parentComp.vue <template> <childComp :fromParentToChild="fro ...

  8. vue -- 父子组件间的事件触发

    1.父组件触发子组件事件 Parent.vue <child ref="child"></child> <div @click="fn&qu ...

  9. vue——父子组件间传值

    (1)父组件给子组件传值(商品详情页): 根据订单类型,判断显示立即购买/立即拼单: 通过props来传递参数 父组件(商品详情页) 父组件调用子组件,在子组件的标签中,通过:数据名称=”数据”的形式 ...

随机推荐

  1. mysql5.7安装部署后初始密码查看以及修改

    一.查看初始密码以下两种方法: 1.找到自己的error.log日志文件,执行自己的命令,红色标记的部分为初始化密码. grep 'temporary password' /data/mysql/er ...

  2. oralce9i部署安装

    为什么还学习oracle9i,因为目前大多数企业的数据依然存储在oracle9i上面,对于数据升级存在很大风险,因此在学习oralce之前,首先熟悉oracle9i也是很有必要的.现在我们先来学习or ...

  3. Codeforces 1167F(计算贡献)

    要点 容易想到排序,然后对于每个数: 人的惯性思维做法是:\(a[i]*(rank1的+rank2的+-)\).然而解法巧妙之处在于直接把所有的加和当成一个系数,然后先假装所有情况系数都是1,接着往上 ...

  4. 【手撸一个ORM】第四步、Expression(表达式目录树)扩展

    到这里,Orm的基架已经搭起来了,接下来就是激动人心的部分,表达式目录树转Sql语句,SqlDataReader转数据实体等等,但是在这之前,我们需要扩展下表达式目录树的方法,以方便后面的相关操作. ...

  5. NET API 分析器

    NET API 分析器 https://www.hanselman.com/blog/WritingSmarterCrossplatformNETCoreAppsWithTheAPIAnalyzerA ...

  6. js 回车提交表单

    一.整个页面用一个回车提交事件: <input type="button" value="回车提交" id="auto" onclic ...

  7. 死磕 java并发包之LongAdder源码分析

    问题 (1)java8中为什么要新增LongAdder? (2)LongAdder的实现方式? (3)LongAdder与AtomicLong的对比? 简介 LongAdder是java8中新增的原子 ...

  8. Intellij idea 创建JAVA项目

    1. 打开软件,new一个project的java项目 2. 点击下一步,此界面可通过模板生成项目,如下图 3. 填写项目名称和项目源码的保存路径,如下图 4. 点击 Finish 完成按钮即可,项目 ...

  9. git从无到有建立一个仓库并上传文件

    第一步,创建仓库 登录自己的码云  第二步,本地操作 1.到你所要上传的文件夹中右键 选择git bash here 2.初始化项目 git init 3.连接远程仓库 刚才我们建立的时候的远程地址就 ...

  10. (2017.10.16) javascript 数据类型转换与操作

    javascript 有 5 种基本数据类型:undefined.null.Boolean.String.Number,还有1 种较复杂的数据类型 Object:各种类型之间可以相互转换,其中有些有趣 ...