3.12 Breadcrumb 面包屑
0x00 简介
组件 Breadcrumb 用于显示当前页面的路径,快速返回之前的任意页面。 本文将深入分析源码,剖析其实现原理,耐心读完,相信会对您有所帮助。源码实现详见packages/breadcrumb/src/ 文件夹下 breadcrumb.vue、 breadcrumb-item.vue 等组件实现。 🔗 组件文档 Breadcrumb 🔗 gitee源码
更多组件剖析详见 👉 📚 Element 2 源码剖析组件总览 。
面包屑组件有两部分 <breadcrumb> 、 <breadcrumb-item>,组件源码都在 packages/breadcrumb/src/ 文件夹下。在项目工程化机制下,每个组件对应各自的文件夹 component-name, 定义导出组件并为其扩展 install 方法,以 commonjs2 规范对每个组件单独打包构建,支持按需引入。
0x01 breadcrumb 组件
breadcrumb.vue 组件是面包屑组件的容器。
template 模板内容
模板创建一个 class 名为.el-breadcrumb的<div>元素作为包裹容器,提供了匿名插槽,将提供breadcrumb-item组件引用内容。
<template>
<div class="el-breadcrumb" aria-label="Breadcrumb" role="navigation">
<slot></slot>
</div>
</template>ARIA 无障碍访问
组件添加了 role 和 aria-label 属性。 role 表示当前元素的类型。aria-label属性用来给当前元素加上的标签描述。
Accessible Rich Internet Applications(ARIA) 是能够让残障人士更加便利的访问 Web 内容和使用 Web 应用的一套机制。 更多内容详见 "ARIA",MDN
attributes 属性
组件定义了 2 个 prop : separator 、separatorClass 。 这两个prop用于在<el-breadcrumb>标签中设置分隔符的形式。
默认使用separator属性,只能是字符串,默认为斜杠/。也可通过设置 separatorClass 使用相应的 iconfont 作为分隔符,格式内容为el-icon-[icon-name],这将使 separator 设置失效。具体逻辑实现详见下文章节 breadcrumb-item 组件#分隔符 。
provide/inject 依赖注入
使用 依赖注入,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
provide 选项允许指定想要提供给后代组件的数据/方法。这里将提供组件 breadcrumb 的 vue 实例 。
在任何后代组件里,使用 inject 选项来指定接收添加在这个实例上的 property。breadcrumb-item组件访问父级组件breadcrumb的实例。
mounted()
实例被挂载后,即 mounted 方法中,通过 $el.querySelectorAll('.el-breadcrumb__item') 在面包屑组件的DOM元素中查找<breadcrumb-item>子节点。为最后一个 <breadcrumb-item> 节点添加属性aria-current="page"。
组件DOM渲染如下,指明<breadcrumb-item>集合中的最后一个代表当前页面。
0x02 breadcrumb-item 组件
breadcrumb-item.vue组件用于实现每一个el-breadcrumb-item 子标签。
template 模板内容
模板创建一个 class 名为el-breadcrumb__item的<span>元素作为标签容器,包含 2 个子节点 标签inerr、分隔符。
标签 inner
该节点渲染一个 class 名为el-breadcrumb__inner的<span>元素, 根据 prop 传入的to值动态添加链接样式。当prop属性 to 是 truthy 时,添加is-link样式。 同时提供了匿名插槽自定义标签内容。
ref 声明用来给元素注册引用信息。role="link" 声明用于识别创建与应用或外部资源的超链接的元素。
attributes 属性
组件定义了 2 个 prop to 、replace用于路由设置。
to路由跳转对象,同vue-router的to。replace在使用 to 进行路由跳转时,启用 replace 将不会向 history 添加新记录。
mounted()
实例被挂载后,根据 to 、replace的传入值动态配置路由设置。
使用
$refs获取标签 inner节点标签元素信息。为节点元素添加
click监听事件
标签监听事件主要用于,点击标签时,判断是否 注册 router 实例 和 设置路由跳转对象(prop 的 to),若都满足,则根据 replace 在使用 to 进行路由跳转时使用不同编程式的导航 。
<router-link :to="...">
router.push(...)
向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
<router-link :to="..." replace>
router.replace(...)
不会向 history 添加新记录,替换掉当前的 history 记录。
分隔符
当属性 separatorClass 是 truthy 时,使用相应的 iconfont 作为分隔符。
否则使用separator属性,默认为斜杠/,此时渲染的 <span> 元素, 其role="presentation" 属性声明用于从元素及其子元素中删除语义含义。
separator、separatorClass属性值通过依赖注入从父组件获取实例,在 mounted 方法中获取父组件的prop中的属性值进行赋值。
0x03 组件样式
src/breadcrumb.scss
组件样式源码 packages\theme-chalk\src\breadcrumb.scss 使用混合指令 b、e、utils-clearfix嵌套生成组件样式。
混合指令utils-clearfix 用于清除浮动。
breadcrumb.scss 生成逻辑如下。
虽然定义了
breadcrumb-item.scss样式文件,但是所有的样式逻辑都在breadcrumb.scss中实现。
lib/breadcrumb.scss
前文可知使用 gulpfile.js编译 scss 文件转换为CSS,经过浏览器兼容、格式压缩,最后生成 packages\theme-chalk\lib\breadcrumb.scss,内容格式如下。
0x04 📚参考
"依赖注入",vuejs.org “组件注入”,vue-router “Using ARIA: Roles, states, and properties”,MDN “Breadcrumb Example”,w3.org "ref",vuejs.org
最后更新于