最近在使用Vue+TypeScript鼓捣本身的组件库,期间参考很多(抄😂)element,iview的源码。发现了一些经常使用的功能的背后,每每是复杂的实现。因而准备写一系列文章,介绍这些组件背后的原理。今天是第三篇,手把手带你实现Collapse组件。数组
参考iview和element的API设计。外层的Collapse组件,主要用于存放内层的CollapseItem组件,以及控制内层CollapseItem组件的显示状态。内层的CollapseItem组件,主要用来存放用户的自定义内容。iview
Collapse主要接收2个参数。ide
在created生命周期中,使用this.$on监听**collapse-item-click**事件,事件参数是CollapseItem的name值。**因为咱们使用的是slot插槽,咱们没有办法直接在子组件中使用this.$emit向上传递事件。咱们将在子组件中使用dispath, 向上广播事件。**this
监听props的value属性,及时响应外部的更新,同时向下广播,通知子组件当前激活的key的修改spa
Collapse组件主要有两个内置的方法。handleCollapseItemClick,处理CollapseItem的点击。设计
setCurrentValue,设置当前激活的CollapseItem的key的集合。根据是否开启手风琴效果,作不一样的处理。同时向子组件广播,当前激活key集合的更改。子组件针对更改,作出显隐处理。递归
向子组件注入父组件的实例,方便子组件获取父组件的属性。生命周期
this.dispatch和this.broadcast本来是Vue1.0中弃用的方法,由于this.dispatch和this.broadcast滥用,会致使整个事件流难以理解。事件
Vue文档中更推荐咱们使用Vuex进行状态管理,可是咱们写的是组件库,使用Vuex会造成额外的依赖。为了方便起见,咱们将重写dispatch和broadcast方法。ip
findChildsComponent方法使用$children属性。向下查找指定name的子组件。若是没有找到,使用递归的方法,查找子组件的子组件。
vm.$children, 当前实例的直接子组件
findParentComponent方法利用$parent属性,向上查找指定name的父组件。若是没有找到,使用递归的方法,查找父组件的父组件。
vm.$parent, 父实例,若是当前实例有的话。
dispatch,和broadcast方法在找到对应的组件后,会在调用组件实例的$emit方法,在组件实例上的$on会监听到$emit传播的事件。
模版主要分为上下两部分,header部分和内容部分。点击header部分,会展开content部分。再次点击后,会收起content的部分。
CollapseItem接收两个属性
在created中监听collapse-active-update事件
接收父组件的注入,collapse属性是父组件的实例。
CollapseItem包含两个方法: