共计 1862 个字符,预计需要花费 5 分钟才能阅读完成。
前言
最近在使用 Vue+TypeScript 鼓捣自己的组件库,期间参考不少(抄????)element,iview的源码。发现了一些常用的功能的背后,往往是复杂的实现。于是准备写一系列文章,介绍这些组件背后的原理。今天是第三篇,手把手带你实现 Collapse 组件。
Collapse
参考 iview 和 element 的 API 设计。外层的 Collapse 组件,主要用于存放内层的 CollapseItem 组件,以及控制内层 CollapseItem 组件的显示状态。内层的 CollapseItem 组件,主要用来存放用户的自定义内容。
模版
Props
Collapse 主要接收 2 个参数。
- value,可以是一个数组或者字符串。如果是数组,代表支持多个 CollapseItem 同时展开。如果是字符串则代表同一时刻只能有一个 CollapseItem 展开。
- accordion,是否支持手风琴效果。
created
在 created 生命周期中,使用 this.$on 监听 **collapse-item-click** 事件,事件参数是 CollapseItem 的 name 值。** 由于我们使用的是 slot 插槽,我们没有办法直接在子组件中使用 this.$emit 向上传递事件。我们将在子组件中使用 dispath, 向上广播事件。**
Data
- currentValue,当前激活的 CollapseItem 的 key 的集合。
Wath
监听 props 的 value 属性,及时响应外部的更新,同时 向下广播,通知子组件当前激活的 key 的修改
Methods
Collapse 组件主要有两个内置的方法。handleCollapseItemClick,处理 CollapseItem 的点击。
setCurrentValue,设置当前激活的 CollapseItem 的 key 的集合。根据是否开启手风琴效果,做不同的处理。同时向子组件广播,当前激活 key 集合的更改。子组件针对更改,做出显隐处理。
Provide
向子组件注入父组件的实例,方便子组件获取父组件的属性。
????this.dispatch & this.broadcast
this.dispatch 和 this.broadcast 原本是 Vue1.0 中弃用的方法,因为 this.dispatch 和 this.broadcast 滥用,会导致整个事件流难以理解。
Vue 文档中更推荐我们使用 Vuex 进行状态管理,但是我们写的是组件库,使用 Vuex 会形成额外的依赖。为了方便起见,我们将重写 dispatch 和 broadcast 方法。
findChildsComponent 方法使用 $children 属性。向下查找指定 name 的子组件。如果没有找到,使用递归的方法,查找子组件的子组件。
vm.$children, 当前实例的直接子组件
findParentComponent 方法利用 $parent 属性,向上查找指定 name 的父组件。如果没有找到,使用递归的方法,查找父组件的父组件。
vm.$parent, 父实例,如果当前实例有的话。
dispatch,和 broadcast 方法在找到对应的组件后,会在调用组件实例的 $emit 方法,在组件实例上的 $on 会监听到 $emit 传播的事件。
CollapseItem
模版
模版主要分为上下两部分,header 部分和内容部分。点击 header 部分,会展开 content 部分。再次点击后,会收起 content 的部分。
Props
CollapseItem 接收两个属性
- title, CollapseItem 的标题
- name, CollapseItem 的唯一标识,当 Collapse 组件的 currentValue 属性,包含这个唯一标识时,CollapseItem 会展开。
created
在 created 中监听 collapse-active-update 事件
Data
- isActive, 根据父组件的 currentValue 属性,判断当前 CollapseItem 是否需要展开。
Inject
接收父组件的注入,collapse 属性是父组件的实例。
Methods
CollapseItem 包含两个方法:
- handleCollapseItemClick,点击 CollapseItem,向上广播 ’collapse-item-click’ 事件,参数是当前组件的 name。
- handleCollapseActiveUpdate,父组件通知子组件当前激活 collapseItem 集合的更改,CollapseItem 判断自身的 key 是否在激活的 collapseItem 集合中。做出显隐处理。