好消息:为了更好的规划和组织内容,今后每期内容之后能将预告下期的主题,欢迎大家补充

组件的分类

  1. 常规页面组件,由 vue-router 产生的每个页面,它本质上也是一个组件(.vue),主要承载当前页面的 HTML 结构,会包含数据获取、数据整理、数据可视化等常规业务。
  2. 功能性抽象组件,不包含业务,独立、具体功能的基础组件,比如日期选择器、弹窗警告等。这类组件作为项目的基础控件,会被大量使用,因此组件的 API 进行过高强度的抽象,可以通过不同配置实现不同的功能。
  3. 业务组件,它不像第二类独立组件只包含某个功能,而是在业务中被多个页面复用的,它与独立组件的区别是,业务组件只在当前项目中会用到,不具有通用性,而且会包含一些业务,比如数据请求;而独立组件不含业务,在任何项目中都可以使用,功能单一,比如一个具有数据校验功能的输入框。

组件的关系

父子组件

父子关系即是组件 A 在它的模板中使用了组件 B,那么组件 A 就是父组件,组件 B 就是子组件。

兄弟组件

两个组件互不引用,则为兄弟组件。

使用组件的时候:

跨级组件

就是在父子关系中,中间跨了很多个层级

组件的构成

一个再复杂的组件,都是由三部分组成的:prop、event、slot,它们构成了 Vue.js 组件的 API。

属性 prop

prop 定义了这个组件有哪些可配置的属性,组件的核心功能也都是它来确定的。写通用组件时,props 最好用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值,这点在组件开发中很重要,然而很多人却忽视,直接使用 props 的数组用法,这样的组件往往是不严谨的。

插槽 slot

插槽 slot,它可以分发组件的内容。和 HTML 元素一样,我们经常需要向一个组件传递内容,像这样:

可能会渲染出这样的东西:

Error!Something bad happended.

幸好,Vue 自定义的 元素让这变得非常简单:

如你所见,我们只要在需要的地方加入插槽就行了——就这么简单!

自定义事件 event

两种写法:

  • 在组件内部自定义事件event

通过 $emit,就可以触发自定义的事件 on-click ,在父级通过 @on-click 来监听:

  • 用事件修饰符 .native直接在父级声明

所以上面的示例也可以这样写:

如果不写 .native 修饰符,那上面的 @click 就是自定义事件 click,而非原生事件 click,但我们在组件内只触发了 on-click 事件,而不是 click,所以直接写 @click 会监听不到。

组件的通信

ref 和 $parent 和 $children

Vue.js 内置的通信手段一般有两种:

  • ref:给元素或组件注册引用信息;
  • $parent / $children:访问父 / 子实例。

用 ref 来访问组件(部分代码省略):

$parent 和 $children 类似,也是基于当前上下文访问父组件或全部子组件的。

这两种方法的弊端是,无法在跨级或兄弟间通信,比如下面的结构:

// parent.vue

我们想在 component-a 中,访问到引用它的页面中(这里就是 parent.vue)的两个 component-b 组件,那这种情况下,是暂时无法实现的,后面会讲解到方法。

v-model

父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值

$attrs和$listeners

如果父组件A下面有子组件B,组件B下面有组件C,这时如果组件A想传递数据给组件C怎么办呢? Vue 2.4开始提供了$attrs和$listeners来解决这个问题,能够让组件A之间传递消息给组件C。

provide / inject

一种无依赖的组件通信方法:Vue.js 内置的 provide / inject 接口

provide / inject 是 Vue.js 2.2.0 版本后新增的 API,在文档中这样介绍 :

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。

假设有两个组件: A.vue 和 B.vue,B 是 A 的子组件:

需要注意的是:

provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

只要一个组件使用了 provide 向下提供数据,那其下所有的子组件都可以通过 inject 来注入,不管中间隔了多少代,而且可以注入多个来自不同父级提供的数据。需要注意的是,一旦注入了某个数据,那这个组件中就不能再声明 这个数据了,因为它已经被父级占有。

provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。然后有两种场景它不能很好的解决:

  • 父组件向子组件(支持跨级)传递数据;
  • 子组件向父组件(支持跨级)传递数据。

这种父子(含跨级)传递数据的通信方式,Vue.js 并没有提供原生的 API 来支持,下面介绍一种在父子组件间通信的方法 dispatch 和 broadcast。

派发与广播——自行实现 dispatch 和 broadcast 方法

要实现的 dispatch 和 broadcast 方法,将具有以下功能:

在子组件调用 dispatch 方法,向上级指定的组件实例(最近的)上触发自定义事件,并传递数据,且该上级组件已预先通过 $on 监听了这个事件;

相反,在父组件调用 broadcast 方法,向下级指定的组件实例(最近的)上触发自定义事件,并传递数据,且该下级组件已预先通过 $on 监听了这个事件。

因为是用作 mixins 导入,所以在 methods 里定义的 dispatch 和 broadcast 方法会被混合到组件里,自然就可以用 this.dispatch 和 this.broadcast 来使用。

这两个方法都接收了三个参数,第一个是组件的 name 值,用于向上或向下递归遍历来寻找对应的组件,第二个和第三个就是上文分析的自定义事件名称和要传递的数据。

可以看到,在 dispatch 里,通过 while 语句,不断向上遍历更新当前组件(即上下文为当前调用该方法的组件)的父组件实例(变量 parent 即为父组件实例),直到匹配到定义的 componentName 与某个上级组件的 name 选项一致时,结束循环,并在找到的组件实例上,调用 $emit 方法来触发自定义事件 eventName。broadcast 方法与之类似,只不过是向下遍历寻找。

来看一下具体的使用方法。有 A.vue 和 B.vue 两个组件,其中 B 是 A 的子组件,中间可能跨多级,在 A 中向 B 通信:

下级组件已预先通过 $on 监听了这个事件

同理,如果是 B 向 A 通信,在 B 中调用 dispatch 方法,在 A 中使用 $on 监听事件即可。

以上就是自行实现的 dispatch 和 broadcast 方法,可以看到饿了么、IView等UI框架都是采用这种方式实现组件间通讯,大家可以去github上阅读相关的源码进行学习。

找到任意组件实例——findComponents 系列方法(Iview的经典方法)

它适用于以下场景:

  • 由一个组件,向上找到最近的指定组件;
  • 由一个组件,向上找到所有的指定组件;
  • 由一个组件,向下找到最近的指定组件;
  • 由一个组件,向下找到所有指定的组件;
  • 由一个组件,找到指定组件的兄弟组件。

5 个不同的场景,对应 5 个不同的函数,实现原理也大同小异。

1、向上找到最近的指定组件——findComponentUpward

比如下面的示例,有组件 A 和组件 B,A 是 B 的父组件,在 B 中获取和调用 A 中的数据和方法:

2、向上找到所有的指定组件——findComponentsUpward

3、向下找到最近的指定组件——findComponentDownward

4、向下找到所有指定的组件——findComponentsDownward

5、找到指定组件的兄弟组件——findBrothersComponents

相比其它 4 个函数,findBrothersComponents 多了一个参数 exceptMe,是否把本身除外,默认是 true。寻找兄弟组件的方法,是先获取 context.$parent.$children,也就是父组件的全部子组件,这里面当前包含了本身,所有也会有第三个参数 exceptMe。Vue.js 在渲染组件时,都会给每个组件加一个内置的属性 _uid,这个 _uid 是不会重复的,借此我们可以从一系列兄弟组件中把自己排除掉。

Event Bus

有时候两个组件之间需要进行通信,但是它们彼此不是父子组件的关系。在一些简单场景,你可以使用一个空的 Vue 实例作为一个事件总线中心(central event bus):

vuex

如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。 详情可参考:https://vuex.vuejs.org/zh-cn/

下期预告:

JavaScript设计模式之单例模式(Singleton Pattern)

如果大家有好的主题,可以在下方留言,我会准备相关的内容在后续发布


参考文章:

https://segmentfault.com/a/1190000018241972

https://github.com/iview/iview/blob/2.0/src/mixins/emitter.js

axure日期选择器组件_vue干货分享,超过六种组件通信方法讲解和精髓归纳相关推荐

  1. axure日期选择器组件_Vue原理解析(十):搞懂事件API原理及在组件库中的妙用

    在vue内部初始化时会为每个组件实例挂载一个this._events私有的空对象属性: vm._events = Object.create(null) // 没有__proto__属性 这个里面存放 ...

  2. axure日期选择器控件_JavaFX 控件 - 输入 (Control - Inputs)

    本章重点内容 介绍JavaFX常用输入控件,从 GitHub 或 Gitee下载详细demo代码. 按钮.单选框.复选框等 适用范围 根据官方文档 javafx.scene.control 编写,适合 ...

  3. 数据库迁移_【干货分享】DM数据库迁移方法(物理迁移)

    在数据库的维护过程中,可能涉及换服务器,或者需要现网数据库环境测试的情况,这时,最简单快速的办法就是将源数据库相关的文件拷贝到目标主机,然后注册数据库实例服务.这就是数据库的物理迁移过程,可以是从wi ...

  4. vue请求数据传给子组件_vue.js基础,父组件如何向子组件传递数据「607」

    本文只有一个学习点. 父组件如何向子组件传递数据. 一起学习,更多文章请关注我的头条号,我是落笔承冰. 一.先创建一张空白网页index.html,在head标签里设置好vue的链接库. 二.写一个绑 ...

  5. 达梦数据库日期格式化_【干货分享】DM7中时间类型的使用介绍

    在数据库的日常使用过程中,无论是记录服务启动时间,还是存储前端应用中的订单时间,都离不开使用各类日期类型,本文就将给大家介绍DM7中各种时间类型的区别和使用注意事项. 一.DM7中时间日期类型简介 D ...

  6. 【干货分享】红黑树硬核讲解

    1 引言 预防针:红黑树本来就是基本算法中的难点,所以看此文时建议先有点预备心理或知识铺垫,没接触过RBT而直接看此文的话,绝对懵逼. 为了数据的查询跟增删方便,系统引入了二叉查找树,它具有左节点 & ...

  7. pls-00302: 必须声明 组件_vue学习手册-单文件组件使用

    单文件组件使用(.vue格式) 在当前模板使用一个组件,须满足两个条件: 1,引入组件,import xx from './xxx' 2,在components里面声明(意思就是注册该组件) 例如: ...

  8. vue手风琴组件_Vue 2的Badger手风琴组件

    vue手风琴组件 Vue-Badger手风琴 (vue-badger-accordion) Badger-Accordion Component for Vue 2.0. Vue 2.0的Badge- ...

  9. vue 拓扑组件_Vue 集成 vis-network 实现网络拓扑图的方法_心病_前端开发者

    vis. https://visjs.org/ vs  code 下安装命令 npm install vis-network 在 const vis = require("vis-netwo ...

最新文章

  1. 美团提出基于隐式条件位置编码的Transformer,性能优于ViT和DeiT
  2. 时雨月五| AI机器学习实战の电磁导航智能车中神经网络应用的问题与思考
  3. Linux下运行C语言程序
  4. python3 循环写入一对多键值对_为什么Python 3.6以后字典有序并且效率更高?
  5. oracle 批量修改表结构,关于Oracle批量修改表结构相关内容的整理
  6. 树的计数(prufer序列 或 purfer序列)
  7. Redis中的事务和watch(乐观锁)
  8. New module changes in Go 1.16
  9. 2021年中国成人商店市场趋势报告、技术动态创新及2027年市场预测
  10. java重新连接tcp,如何处理TCP客户端丢弃和重新连接
  11. Spark:聚类算法之LDA主题模型算法
  12. 发现美,欣赏美,美之我见
  13. 定点数乘法运算:Booth算法(补码一位乘法)C 实现
  14. Pycharm CPU占用100%
  15. 品牌该如何做好软文营销?软文营销怎么规避风险?
  16. 下载c语言软件后怎么解压,手机怎么解压文件 盘点常用手机压缩打包解压文件应用...
  17. 什么是迭代计算机编程,什么是递归?什么是迭代?
  18. 【多数据中心】分布式数据同步设计方案
  19. http协议之长连接与短连接服务器,长连接短连接
  20. (11)RabbitMQ的mandatory、immediate和ReturnListener

热门文章

  1. 腾讯暑期日常实习前端面试
  2. Shadow DOM的理解
  3. php 返回的缓存数据,基于PHP输出缓存(output_buffering)的深入理解
  4. 图书管理系统html_你的毕业设计是 XX 管理系统吗?
  5. SpringMVC 另一种基于xml的处理器、适配器(了解)
  6. alan turing_深入探讨Alan Turing的生活和遗产:5本及更多书籍
  7. devops_您无法购买DevOps
  8. Git的使用_思维导图
  9. 理解node.js(Understanding node.js)
  10. Bootstrap按钮的状态