Django restframework加Vue打造前后端分离的网站(十六)添加面包屑导航
在网站里,往往会有多级目录,比如进入了项目主页-人员管理-具体人员-编辑,这时需要告知用户目前是处于什么地方,给予用户导航的便利。
面包屑breadcrumb可以展示当前页面在系统结构中的位置,用户可以理解自己进入的目录结构,并可以点击不同层级面包屑的链接来进入前一级页面或直接进入主页。
比如如下是在antd官方的一个展示例子。
我们可以在每个页面中写明导航的菜单级
<template>
<a-breadcrumb>
<a-breadcrumb-item>Home</a-breadcrumb-item>
<a-breadcrumb-item><a href="">Application Center</a></a-breadcrumb-item>
<a-breadcrumb-item><a href="">Application List</a></a-breadcrumb-item>
<a-breadcrumb-item>An Application</a-breadcrumb-item>
</a-breadcrumb>
</template>
也可以加上图标等
<template>
<a-breadcrumb>
<a-breadcrumb-item href="">
<a-icon type="home" />
</a-breadcrumb-item>
<a-breadcrumb-item href="">
<a-icon type="user" />
<span>Application List</span>
</a-breadcrumb-item>
<a-breadcrumb-item>
Application
</a-breadcrumb-item>
</a-breadcrumb>
</template>
但这种每个页面都写一遍的方式并不理想,尤其是存在写错导航名字的可能性。
于是我们可以定义一个统一的面包屑导航,令其自动获取当前的位置链接。
例如我们可以在router/index.js中为需要展示面包屑的路由里加上文字,然后来获取。
export default new Router({
mode: 'history',
routes: [
...
{
path: '/projects/:project_id',
name: 'project',
component: ProjectDashboard,
meta: {
breadcrumb: 'Dashboard' //这里
}
},
...
]
});
在vue文件中指定从router中获取。
<template>
<a-breadcrumb>
<a-breadcrumb-item href="">
<a-icon type="home" />
</a-breadcrumb-item>
<a-breadcrumb-item href="">
<a-icon type="user" />
<span>Application List {{this.$options.name}}</span> //这里展示vue组件的name
</a-breadcrumb-item>
<a-breadcrumb-item>
{{this.$route.meta.breadcrumb}} //这里展示router中定义的面包屑的名字
</a-breadcrumb-item>
</a-breadcrumb>
</template>
也可以设定循环令页面层级个数自适应。
<template>
<a-breadcrumb class="breadcrumb">
<a-breadcrumb-item v-for="(item, index) in breadList" :key="item.name"> //当然这里的breadList需要自定义并根据条件赋值
<router-link
v-if="item.name != name && index != 1"
:to="{ path: item.path === '' ? '/' : item.path }"
>{{ item.meta.title }}</router-link>
<span v-else>{{ item.meta.title }}</span>
</a-breadcrumb-item>
</a-breadcrumb>
</template>
另外还可以和vue-router结合起来,下面的例子来自官方。实际使用时往往不会将具体的数据放在当前文件里,比如可以存在全局数据管理的store.js中,根据实际条件调整值。
<template>
<div>
<a-breadcrumb :routes="routes">
<template slot="itemRender" slot-scope="{ route, params, routes, paths }">
<span v-if="routes.indexOf(route) === routes.length - 1">
{{ route.breadcrumbName }}
</span>
<router-link v-else :to="`${basePath}/${paths.join('/')}`">
{{ route.breadcrumbName }}
</router-link>
</template>
</a-breadcrumb>
<br />
{{ $route.path }}
</div>
</template>
<script>
export default {
data() {
const { lang } = this.$route.params;
return {
basePath: '/components/breadcrumb',
routes: [
{
path: 'index',
breadcrumbName: 'home',
},
{
path: 'first',
breadcrumbName: 'first',
children: [
{
path: '/general',
breadcrumbName: 'General',
},
{
path: '/layout',
breadcrumbName: 'Layout',
},
{
path: '/navigation',
breadcrumbName: 'Navigation',
},
],
},
{
path: 'second',
breadcrumbName: 'second',
},
],
};
},
};
</script>