3.18 Collapse 折叠面板

简介

组件 Collapse 可以折叠/展开的内容区域。 本文将深入分析源码,剖析其实现原理,耐心读完,相信会对您有所帮助。

Collapse 折叠面板组件有两部分 <el-collapse><el-collapse-item>。组件源码详见packages/collapse/src/ 文件夹下 collapse.vuecollapse-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 : accordionvalue

  • 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-itemdiv 元素作为标签容器,包含 2 个子节点 tab 面板标题、tabpanel 面板内容。

根节点

根据传入 prop disabled 动态添加禁用样式 is-disabled

根据计算属性 isActive 动态添加激活样式 is-active

计算属性isActive通过注入获取顶层组件中属性activeNames,判断当前面板是否激活。

tab 面板标题

该节点是一个设置了role,aria-expanded,aria-controls,aria-describedby等 ARIA 属性的 div包裹容器,里面嵌套了一个 class 名为 el-collapse-item__headerdiv 元素,用于展示面板标题。

面板标题节点元素内部包含了:

  • 一个名为title具名插槽设置,使用 prop 的 title值作为其的后备;

  • 一个图标用于展示面板的激活状态。

当面板被禁用, 元素不可聚焦(tabindex="0" 表示元素是可聚焦的)。

按键修饰符 keyup space``enter用于监听键盘事件。事件修饰符stop阻止单击事件继续传播。

方法handleEnterClick 用于触发顶层组件的 item-click 事件 。

添加了 click focus blur 等事件监听。

折叠状态切换时,图标动效使用 rotate 旋转实现。

tabpanel 面板内容

该节点一个 class 名为 el-collapse-item__wrapdiv 元素作为内容容器,包含一个子节点 class 名为 el-collapse-item__contentdiv 元素,里面提供了匿名插槽,用于面板内容展示。

该节点使用了 collapse-transition 组件,用于实现折叠展开过渡效果。根据面板激活状态(计算属性isActive)进行显隐 v-show="isActive"

组件样式

组件样式源码 packages\theme-chalk\src\collapse.scss使用混合指令嵌套生成组件样式。

📚参考&关联阅读

"依赖注入",vuejs.org “组件注入”,vue-router "ARIA(Accessible Rich Internet Applications)",MDN

最后更新于