如下图 ,公司手头上的项目有一个需求,要求在一个页面通过路由渲染无限级子部门的详细数据,并且可以 通过页面上的按钮切换上下级,也可以通过点击头部的面包屑切换当前任意层级的部门。
首次进入路由会根据公司 id 查询到所有一级下属部门并展示,同时每个部门都有一个唯一标识(id),任意层级的部门都有此 id ,可以通过 id 查询到相应的子级部门数据。
点击下一级会在当前路由的path后添加下级的部门 id 用于查询部门信息,相当于修改了 $route.fullPath,同时我监听路径的变化,一旦发生变化即可向后台发起请求以展示子级部门数据
并且地址和面包屑是相对应的,点击相应的面包屑可以跳转到对应路由
先配置路由,父路由 department 下有两个子路由分别是 ''(匹配空参数)和 :id*
(匹配嵌套路由),注意,这里有个坑: 要注意,以 /
开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。 详见官方文档。
// 人员管理
{
path: `/department`,
name: 'department',
component: () => import('@/components/personnelManage/department/department.vue'),
meta: {
requireAuth: true,
title: '部门'
},
children: [
{
path: '',
component: () => import('@/components/personnelManage/department/department.vue'),
meta: {
requireAuth: true,
title: '部门'
},
},
{
path: `:id*`,
component: () => import('@/components/personnelManage/department/department.vue'),
meta: {
requireAuth: true,
title: `部门`
},
},
]
}
添加一个计算属性 paths 用来将查询参数用 / 分割成一个数组,渲染面包屑需要全部数组,查询当前部门信息则只需要数组最后一项
get paths(): any {
return (
this.$route.params &&
this.$route.params.id &&
this.$route.params.id.split("/")
);
}
渲染面包屑,赋予点击事件,点击后路由会 push 到当前查询的子部门 id
// html
<md-chip md-clickable @click="onClickChip( i + 1 )" :key="i" v-for="(p, i) in paths">{{p}}</md-chip>
// js
private onClickChip(i: any): void {
this.$router.push({
path: `/department/${this.paths.slice(0, i).join("/")}`
});
}
公共请求方法,如果在根目录则 paths 为 undefined,这时将通过公司id展示一级部门信息,如果不为根目录将通过部门 id 查询下级部门信息并展示,并且在第一次初始化将渲染页面
private ready() {
if (this.paths == undefined) {
console.log(this.paths);
let comId: number = getInfo().comId;
getData(personnelManageApi.getAllDep(comId), this);
} else {
getDep(
personnelManageApi.getChildDep(this.paths[this.paths.length - 1]),
this
);
console.log(this.paths[this.paths.length - 1]);
}
}
private created() {
this.ready();
}
然后是很重要的一步,为 paths 设置监听,当 paths 发生变化时重新调用请求方法更新数据
@Watch("paths", { immediate: true, deep: true })
onRouteChanged(val: string, oldVal: string) {
console.log(val);
this.ready();
}
最后愉快的 commit