3.18 Collapse 折叠面板
简介
组件 Collapse 可以折叠/展开的内容区域。 本文将深入分析源码,剖析其实现原理,耐心读完,相信会对您有所帮助。
Collapse 折叠面板组件有两部分 <el-collapse> 、 <el-collapse-item>。组件源码详见packages/collapse/src/ 文件夹下 collapse.vue、 collapse-item.vue 等组件。在项目工程化机制下,每个组件对应各自的文件夹 component-name, 定义导出组件并为其扩展 install 方法,以 commonjs2 规范对每个组件单独打包构建,支持按需引入。🔗 组件文档 Collapse 🔗 gitee 源码
本专栏的 gitbook 版本地址已经发布 anduril.gitbook.io/learning-el… ,内容同步更新中!
更多组件剖析详见 👉 📚 Element 2 源码剖析组件总览 。
collapse 组件
collapse.vue 是折叠面板的顶层组件。
template 模板内容
模板创建一个 class 名为.el-collapse的<div>元素作为包裹容器,提供了匿名插槽,将提供collapse-item组件引用内容。
<template>
<div class="el-collapse" role="tablist" aria-multiselectable="true">
<slot></slot>
</div>
</template>
<script>
export default {
name: "ElCollapse",
componentName: "ElCollapse",
};
</script>ARIA 无障碍访问
role 表示当前元素的类型。aria-multiselectable表示当前元素是否可多选。
attributes 属性
组件定义了 2 个 prop : accordion 、value 。
accordion用于是否开启手风琴模式。value用于当前激活的面板,默认值为[],如果是手风琴模式,绑定值类型需要为 string,否则为 array。
组件的 activeNames 属性表示激活的面板数组(可同时展开多个面板),将value 转化为数组(因为value 会传入 String, Number值 )。 value 添加了监听器用于更新 activeNames 。
provide/inject 依赖注入
使用 依赖注入,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
将 collapse 组件实例提供给后代组件。
在任何后代组件里,使用 inject 选项来指定接收添加在这个实例上的 property。collapse-item组件访问父级组件collapse的实例。
created()
组件实例创建后,注册 item-click事件监听,回调函数 handleItemClick更新激活的面板。
子组件中调用 dispatch触发collapse 组件的item-click事件。
methods & events
handleItemClick方法用于item-click事件回调。根据是否手风琴模式根据点击选项更新最activeNames 值。
setActiveNames 方法用于更新 activeNames值,调用 $emit触发当前组件实例上的change事件 。
Collapse-item 组件
Collapse-item.vue用于渲染面板内容。
template 模板内容
模板创建一个 class 名为 el-collapse-item 的 div 元素作为标签容器,包含 2 个子节点 tab 面板标题、tabpanel 面板内容。
根节点
根据传入 prop disabled 动态添加禁用样式 is-disabled。
根据计算属性 isActive 动态添加激活样式 is-active。
计算属性isActive通过注入获取顶层组件中属性activeNames,判断当前面板是否激活。
tab 面板标题
tab 面板标题该节点是一个设置了role,aria-expanded,aria-controls,aria-describedby等 ARIA 属性的 div包裹容器,里面嵌套了一个 class 名为 el-collapse-item__header 的 div 元素,用于展示面板标题。
面板标题节点元素内部包含了:
一个名为
title具名插槽设置,使用 prop 的title值作为其的后备;一个图标用于展示面板的激活状态。
当面板被禁用, 元素不可聚焦(tabindex="0" 表示元素是可聚焦的)。
按键修饰符 keyup space``enter用于监听键盘事件。事件修饰符stop阻止单击事件继续传播。
方法handleEnterClick 用于触发顶层组件的 item-click 事件 。
添加了 click focus blur 等事件监听。
折叠状态切换时,图标动效使用 rotate 旋转实现。
tabpanel 面板内容
tabpanel 面板内容该节点一个 class 名为 el-collapse-item__wrap 的 div 元素作为内容容器,包含一个子节点 class 名为 el-collapse-item__content 的 div 元素,里面提供了匿名插槽,用于面板内容展示。
该节点使用了 collapse-transition 组件,用于实现折叠展开过渡效果。根据面板激活状态(计算属性isActive)进行显隐 v-show="isActive"
组件样式
组件样式源码 packages\theme-chalk\src\collapse.scss使用混合指令嵌套生成组件样式。
📚参考&关联阅读
"依赖注入",vuejs.org “组件注入”,vue-router "ARIA(Accessible Rich Internet Applications)",MDN
最后更新于