热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Vue中的父子组件通讯以及使用sync同步父子组件数据

这篇文章主要介绍了Vue中的父子组件通讯以及使用sync同步父子组件数据,对vue感兴趣的同学,可以参考下

前言

父子组件通讯,可分为两种情况:

1. 父组件向子组件中传递数据
2. 子组件向父组件中传递数据

一般情况下, 1中情况可通过props解决数据传递的问题, 这里就不多赘述了。

子组件向父组件中传递数据

主要谈谈2中情景的实现,有三种方式:

一. 通过props,父组件向子组件中传递数据和改变数据的函数,通过在子组件中调用父组件传过来的函数,达到更新父组件数据(向父组件传递数据)的作用(子组件中需要有相应的响应事件)

二. 通过在子组件中触发一个 自定义事件(vm.$emit),将数据作为vm.$emit方法的参数,回传给父组件用v-on:[自定义事件]监听的函数

三.通过ref对子组件做标记,父组件可以通过vm.$refs.[子组件的ref].[子组件的属性/方法]这种方式直接取得子组件的数据

下面我将一 一展示

一. 通过props从父向子组件传递函数,调用函数改变父组件数据

这里就不做代码展示了

一来是因为相对比较简单
二来是因为这种方式显然不是Vue中的最佳实践(在react中倒比较常见)
想要看代码的话可以看这里:《【Vue】浅谈Vue不同场景下组件间的数据交流》http://www.cnblogs.com/penghuwan/p/7286912.html (在兄弟组件的数据交流那一节)

二. 通过自定义事件从子组件向父组件中传递数据

我们可以在子组件中通过$emit(event, [...参数])触发一个自定义的事件,这样,父组件可以在使用子组件的地方直接用 v-on来监听子组件触发的事件, 并且可以在监听函数中依次取得所有从子组件传来的参数

例如:
在子组件中某个部分写入:

this.emit('eventYouDefined', arg);

然后你就可以在父组件的子组件模板里监听:
// 这里是父组件的Template:

下面是一个实例

父组件


 

 

子组件:


 

 

在点击子组件中的“发送数据”按钮前, 父组件还没有接受到数据(text为空字符串), 则通过 {{ text || '暂无数据' }}将显示默认文本:‘暂无数据'

点击“发送数据”按钮后:

因为sendData自定义事件被触发,通过

this.$emit('sendData', this.text)   //此处的this指向子组件实例)

子组件的text数据被父组件中:

 

中的getSonText函数作为参数接传参受到, 从而完成了从子组件向父组件中的传参过程

三. 通过ref属性在父组件中直接取得子组件的数据(data)

对于我们上面讲的一和二的处理情景来说,有个局限性就是它们都需要以事件机制为基础(无论是像click那样的原生事件还是自定义事件),而在事件发生的时候才能调用函数将数据传递过来

但如果子组件里没有类似“按钮”的东西,因而无法制造原生事件,同时也没办法找到一个触发自定义事件的时机的时候,怎么从子组件向父组件传递数据呢??

这个时候, 我们就只能从父组件中“直接取”子组件的数据了,借助ref属性

ref是我们经常用到的Vue属性,利用它可以简单方便地从本组件的template中取得DOM实例,而实际上,如果你在父组件中为子组件设置ref的话, 就可以直接通过vm.$refs.[子组件的ref].[子组件的属性]去拿到数据啦,例如:

父组件:


 

 

子组件:


 

 

demo:

尚未点击“接受数据”按钮前:

点击接受数据按钮后:

通过sync实现数据双向绑定, 从而同步父子组件数据

通过以上三种方式, 我想你应该能解决绝大多数父子组件通信的场景了,但让我们再仔细考虑一下上面的通信场景,就会发现它们还可能存在的问题:

从子组件向父组件传递数据时,父子组件中的数据仍不是每时每刻都同步的

但在某些特殊的需求场景下,我们可能会希望父子组件中的数据时刻保持同步, 这时候你可能会像下面这样做:

这是父组件中的template:

在子组件中, 我们通过props声明的方式接收foo并使用

props: {
     foo: [type]
}

同时每当子组件中数据改变的时候,通过

this.$emit('update', newValue)

把参数newValue传递给父组件template中监听函数中的"val"。然后通过

val => bar = val

这个表达式就实现了bar = newValue. 这个时候,我们发现父组件中的关键数据bar被子组件改变(相等)了!

通过数据的双向绑定, 父(组件)可以修改子的数据, 子也可以修改父的数据

Vue提供了sync修饰符简化上面的代码,例如:

会被扩展为:

然后你需要在子组件中改变父组件数据的时候, 需要触发以下的自定义事件:

this.$emit("update:foo", newValue)

【注意】你可能觉得这好像和我上面提到的二中的“通过自定义事件(emit)从子组件向父组件中传递数据”的那一节的内容似乎重叠了,。

然而并不是, 两者有着父子组件关系上的不同, 下面我通过一行关键的代码证明它们的区别所在

1.在我们讲解sync的这一小节里, 自定义事件发生时候运行的响应表达式是:
中的 "val => bar = val"

2.在二中的“通过自定义事件从子组件向父组件中传递数据” 里,自定义事件发生时候运行的响应表达式是:
中的 "arg => functionYours(arg)"

对前者, 表达式 val => bar = val意味着强制让父组件的数据等于子组件传递过来的数据, 这个时候,我们发现父子组件的地位是平等的。 父可以改变子(数据), 子也可以改变父(数据)

对后者, 你的functionYours是在父组件中定义的, 在这个函数里, 你可以对从子组件接受来的arg数据做任意的操作或处理, 决定权完全落在父组件中, 也就是: 父可以改变子(数据), 但子不能直接改变父(数据)!, 父中数据的变动只能由它自己决定

下面是一个展示demo:

父组件:


 

 

子组件:


 

 

点击前

点击增加子组件中“增加智力”按钮的时候, 父组件和子组件中的智力参数同时从90变为91

点击增加子组件中“增加膜法”按钮的时候, 父组件和子组件中的智力参数同时从160变为161

数据双向绑定是把双刃剑

从好处上看:

1.它实现了父子组件数据的“实时”同步, 在某些数据场景下可能会使用到这一点
2.sync提供的语法糖使得双向绑定的代码变得很简单

从坏处上看:

它破环了单向数据流的简洁性, 这增加了分析数据时的难度

当sync修饰的prop是个对象

我们对上面的例子修改一下, 把数据包裹在一个对象中传递下来:

父组件


 

 

子组件


 

 

demo同上

不要通过在子组件中修改引用类型props达到“父子组件数据同步”的需求!

父组件的数据传递给子组件, 一般通过props实现, 而在实现“父子组件数据同步”这一需求的时候, 小伙伴们可能会发现一点: 在子组件中修改引用类型的props(如数组和对象)是可行的

1.不仅可以达到同时修改父组件中的数据(因为本来引用的就是同一个数据)
2.而且还不会被Vue的检测机制发现!(不会报错)

但千万不要这样做, 这样会让数据流变得更加难以分析,如果你尝试这样做, 上面的做法可能会更好一些
不要这样做,糟糕的做法:

父组件:


 

 

子组件:


 

 

以上就是Vue中的父子组件通讯以及使用sync同步父子组件数据的详细内容,更多关于Vue的资料请关注其它相关文章!


推荐阅读
  • 本文介绍了如何利用npm脚本和concurrently工具,实现本地开发环境中多个监听服务的同时启动,包括HTTP服务、自动刷新、Sass和ES6支持。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文详细介绍了Git分布式版本控制系统中远程仓库的概念和操作方法。通过具体案例,帮助读者更好地理解和掌握如何高效管理代码库。 ... [详细]
  • 前端开发:从底层到顶端的行业现象解析
    在编程领域,鄙视链现象屡见不鲜,从C语言到Java、.NET等,每个技术栈都有其独特地位。然而,前端开发者尽管常处于鄙视链底端,却在市场需求中备受青睐。本文深入探讨这一现象,并分析前端工程师如何在竞争激烈的市场中脱颖而出。 ... [详细]
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 本周信息安全小组主要进行了CTF竞赛相关技能的学习,包括HTML和CSS的基础知识、逆向工程的初步探索以及整数溢出漏洞的学习。此外,还掌握了Linux命令行操作及互联网工作原理的基本概念。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • 探讨如何高效使用FastJSON进行JSON数据解析,特别是从复杂嵌套结构中提取特定字段值的方法。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文介绍如何使用 NSTimer 实现倒计时功能,详细讲解了初始化方法、参数配置以及具体实现步骤。通过示例代码展示如何创建和管理定时器,确保在指定时间间隔内执行特定任务。 ... [详细]
author-avatar
我不是不是小受
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有