这几天在工作中遇到一个场景:
在项目中,我需要发送请求从后台拉取所有的部门列表作为下拉框的一级菜单,然后需要根据每一个部门的id从后台获取每个部门的所有人员列表。如下图:
乍一看,好像这个需求很容易实现,我只需要在获取每一个部门列表的请求中去拿到id然后在发请求给后台拿到所有的人员列表,并通过一系列数据结构的处理使之成为满足el-cascader要求的结构,如下
//Cascader.vue
<template>
<el-cascader
:options="departments"
v-model="editSubForm.userMessageKey"
@change="handleChange">
</el-cascader>
</template>
<script>
export default {
data(){
return{
departments:[
{label:'部门名',
value:'唯一标识..',
children:[
{label:'人员名称',value:'唯一标识'}
//....
]}
]
}
},
methods:{
// 请求一级菜单 部门列表数据
this.postRequest('/api/departments').then(res =>{
let data = res.data.data
// 根据每一个部门id获取对应的人员列表
data.map(item =>{
this.postRequest(`/api/departments/${item.departmentId}/user_message_key`).then(res =>{
let data = res.data.data
// ....处理数据结构
})
})
})
}
}
</script>
但是,假设此时有100个部门,每个部门有100人,那么进入此页面,我们就需要一次性发送 1+100 次请求。
如果部门更多,因为一直再发请求,对服务器是极大的考验,同时,我们前端页面也会因为频繁发送请求而导致页面卡顿,甚至完全无法操作,此时就需要我们进行懒加载处理。
我们就需要将多次请求拆分,只有当我们点击某一个部门菜单项时,才根据当前点击的部门id去发送请求拿到该部门的所有人员列表信息
废话不多说,直接贴代码,注释写在代码里:
<template>
<el-cascader :props="props" :options="departments" v-model="editSubForm.userMessageKey" @change="handleChange"></el-cascader>
</template>
<script>
import {mapState} from 'vuex';
export default {
data(){
return {
departments:[],
queryDepartmentPeopleUrl:'/api/departments',
props:{
// 启用懒加载
lazy:true,
lazyLoad: (node, resolve) => {
setTimeout(()=>{
console.log(node, resolve);
let { level } = node;
// 部门列表level为0级,下级的人员列表为1级 level为1级
if (level === 1) {
let nodes = null;
// 从服务器拉取部门列表
this.$api
.queryDepartmentsPeople({
count: 100000,
page: 0,
departmentKey: node.value, // 定义的部门key结构
sortDirection: 0,
})
.then((res) => {
console.log(res.data.data);
// 将当前部门人员列表添加到userMessages列表的children中
if (res.data.data.length > 0) {
nodes = res.data.data.map((item) => ({
value: item.keyOnly,
label: item.userInfoName,
// leaf参数设为true,表示没有下级菜单了
// 如果为false,点击还会生成下级菜单
leaf: true,
}));
// 最重要的,别忘了调用resolve()回调方法,只有调用了这行,才会去生成节点
resolve(nodes);
// console.log(nodes);
}else{
// resolve([])目的是为了防止某部门下没有人员资料时,会一直处于loading加载状态
resolve([])
}
});
}else{
resolve([])
}
},2000)
},
}
}
},
computed:{
// 部门列表我是有存储到vuex中的
...mapState({
departmentList:state => state.departmentList
}),
// 或者放到 created()钩子函数中对部门列表进行处理
departments(){
return this.departmentList.map(item =>({
value:item.keyOnly,
label:item.name,
level:0
}))
}
},
}
最终效果如下: