【技术博客】动态面包屑导航
很久很久以前,在大森林的边上住着一个贫穷的樵夫,他与妻子和两个孩子相依为命。他的儿子名叫汉赛尔,女儿名叫格莱特。后来樵夫的妻子去世了,后母计划把两个孩子带到森林的深处,然后趁他们睡着的时候跑掉。汉赛尔无意中知道了后母的计划,于是偷偷地把一块面包藏在了口袋里。在去森林的路上,汉赛尔悄悄地捏碎了他的面包,并不时地停下脚步,把碎面包屑撒在路上。后母趁孩子们睡着的时候溜掉了,汉赛尔和格莱特醒来已是一片漆黑。汉赛尔安慰他的妹妹说:"等太阳一出来,我们就看得见我撒在地上的面包屑了,它一定会指给我们回家的路。"
我们为什么需要面包屑?
"面包屑"在我们的网站导航中,同样也是一种历史记录的方式,达到线性导航的目的。
在网页访问中,用户时常需要知道目前所处的页面位置,或者回到之前访问的网页中。这就需要面包屑导航(Bread crumbs)。
面包屑导航的主要作用如下:
-
表明当前所处的位置,方面用户感知页面之间的所属关系;
-
提供返回到之前各个层级的入口,作为主导航的补充;
-
帮助用户快速掌握网站的架构方式。
静态面包屑
在Alpha版中,我们实现了静态面包屑,即对于每个页面,有固定的面包屑导航栏,标识该页面的父亲页面。静态面包屑的导航逻辑时由我们在编码的过程中提前决定的。
实现方法
由于静态面包屑是我们可以提前决定的,因此实现比较简单,我们只需要标识好每个页面有哪些父亲页面即可。
我们使用router中的数据结构记录下其父亲界面的名字和path。例如,对于[路书编辑页]这个界面,其router如下:
{
path: '/editor',
name: 'Editor',
component: () => import('../views/RoadmapEditorView.vue'),
meta: {
name: ['路书目录', '路书编辑页'],
path: ['/RoadmapTable', '/editor'],
},
}
在界面上,我们将每个页面的父亲页面输出为面包屑即可:
<Breadcrumb :style="{margin: '16px 0px'}">
<BreadcrumbItem
:to="$route.meta.path[index]"
v-for="(item, index) in $route.meta.name"
:key="index">
{{ item }}
</BreadcrumbItem>
</Breadcrumb>
为什么需要动态面包屑?
静态面包屑可以在很多情况下满足我们的需求,但是页面的组织形式可能不是简单的树状结构,一个页面可能有多个父亲页面(如在本网站中,article markdown editor页面的父亲界面可能为文献管理,也可以是路书界面)。因此,我们需要记录下用户的历史访问操作,建立一个动态的面包屑,为不同用户访问路径建立不同的面包屑。这点是静态面包屑导航无法实现的。
如何实现动态面包屑?
动态面包屑需要维护用户访问的界面。我们通过一个全局的[用户访问栈]来实现,用户在到达每个界面时,我们将其访问的页面入栈。
为了保持面包屑的页面顺序,我们为每个页面设置一个level属性,在A页面入栈的过程中,将level大于等于该A页面的其他页面出栈。
具体实现如下:
router出我们增加[level]和[nickName]两个属性,例如:
{
path: '/articleTable',
name: 'ArticleTable',
component: () => import('../views/ArticleTableView.vue'),
meta: {
nickName: '文献目录',
level: 2,
},
}
我们建立了一个全局[用户访问栈],在到达每个页面时,将该页面"入栈":
export default function pushRouter(name, nickName, fullPath, level) {
let hasHomePage = false;
for (let i = 0; i < window.routerStack.length; i += 1) {
if (window.routerStack[i].nickName === '主页') {
hasHomePage = true;
} else if ((window.routerStack[i].level >= level || window.routerStack[i].name === undefined)) {
window.routerStack.splice(i, 1);
i -= 1;
}
}
if (!hasHomePage) {
window.routerStack.push({ name: 'Welcome', nickName: '主页', fullPath: '/', level: 1 });
}
if (level > 1) {
window.routerStack.push({ name, nickName, fullPath, level });
}
}
动态面包屑的效果
使用我们的方法可以实现动态面包屑的既定效果。
- 从路书编辑页进入文献笔记
- 从文献目录进入文献笔记