vue+element Ui 树型组件tree懒加载+搜索框远程请求数据为平铺类型
本人之前一直是耕耘后台研发,最近接了个小需求需要接触到vue,记录一下我遇到的一些前端解决时间长的问题
需求:
1:每次动态请求接口获取下一节点数据
2:接口返回的数据是list,不带子节点,用pid来维护父子之间的关系
3:带有搜索框,搜索框为请求远程数据,数据为不带子节点数据用pid来维护
4:简单!!!
页面:
需要组件:
下载三方插件 使用arrayTotree插件 将扁平化数组转换为树形结构数组 并赋值给list
npm install array-to-tree --save
import arrayToTree from ‘array-to-tree’
data中的自定义数组 = arrayToTree(获取请求的数组, { parentProperty: ‘父级id’, customID: ‘二级id’});
代码:
<template>
<el-tabs v-model="activeName">
<el-tab-pane label="成员" name="first">
<!--左边-->
<el-container>
<el-aside width="200px">
<el-input
placeholder="Search by name"
prefix-icon="el-icon-search"
v-model="inputStr"
class="name-email-search"
size="small"
clearable
@blur="initSearch"
@clear="initSearch">
</el-input>
<el-tree
:data="treeList"
ref="tree"
class="vue-tree"
lazy
:load="loadNode"
:highlight-current="true"
:node-key="nodeKey"
@node-click="nodeClick"
:expand-on-click-node="false"
:props="defaultProps"
></el-tree>
</el-aside>
<!--右边-->
<el-main>{{str}}</el-main>
</el-container>
</el-tab-pane>
<el-tab-pane label="组织" name="second">组织
</el-tab-pane>
</el-tabs>
</template>
<script>
import {childNodes, search} from "../api/dept";
import arrayToTree from 'array-to-tree';
import {treeList} from "../api/system/msg";
export default {
data() {
return {
activeName: 'first',
//输入框输入的值
inputStr: '',
defaultProps: {
children: "children",
label: "name",
isLeaf: "isLeaf",
},
currentNodeKey: "",
//当前树用到的list
treeList: [],
str: 'aaa'
};
},
methods: {
//搜索框
async initSearch(resolve) {
const param = {
orders: [],
conditions: [{field: 'name', value: this.inputStr}]
};
const res = await search(param)
//将搜索出来的扁平数据转换成tree树状数据
//再将搜索出来的数据替换之前加载的tree数据
this.treeList = arrayToTree(res.data.data,
{parentProperty:'pid', customID:'deptId'}) ;
},
// 懒加载获取树形结构
loadNode(node, resolve) {
//调用接口时,我们的需求是第一级传参为0,后面为当前节点的唯一表示id,可以根据需求而定
// node.level为0时,就是tree的第一级
const spaceParentGuid = node.level === 0 ? 0 : node.data.deptId
childNodes(spaceParentGuid).then(({data}) => {
resolve(
data.data.map(item => {
return {
...item,
leaf: !item.hasChildren // 此参数用来判断当前节点是否为叶子节点
}
})
)
})
},
nodeClick() {
this.str = 'changede';
}
},
mounted() {
}
};
</script>
后端查询接口接口返回数据格式:
{
"success": true,
"message": null,
"data": [
{
"deptId": 1,
"pid": 0,
"subCount": 0,
"name": "默认组织",
"deptSort": 0,
"createBy": null,
"updateBy": null,
"createTime": 1682229715,
"updateTime": 1682229715,
"hasChildren": false,
"leaf": true,
"top": true
},
{
"deptId": 1231231,
"pid": 354122786547134460,
"subCount": 0,
"name": "xw部门2",
"deptSort": 999,
"createBy": null,
"updateBy": null,
"createTime": null,
"updateTime": null,
"hasChildren": false,
"leaf": true,
"top": false
}]
}
到上面的就结束了,下面是是笔者自己记录的,记得替换成自己的
请求的接口:dept.js
import request from '../utils/request'
const localHost = 'http://localhost:8081'
export function search(data) {
return request({
url: localHost+'/plugin/dept/search',
method: 'post',
data
})
}
export function childNodes(data) {
return request({
url: localHost+'/plugin/dept/childNodes/'+data,
method: 'post',
data
})
}
接口拦截器:request.js
import axios from 'axios'
import Config from '@/settings'
import { getToken } from '../utils/auth'
const TokenKey = Config.TokenKey
let service = axios.create({
timeout: 10000
})
// request interceptor
service.interceptors.request.use(
config => {
console.log(getToken())
config.headers[TokenKey] =getToken() ;
return config
},
error => {
return Promise.reject(error)
}
)
// Response interceptor for API calls
service.interceptors.response.use(
response => {
return response;
},
error => {
if(error.response.status == 403){
refreshToken()
}
}
);
const refreshToken= ()=>{
// gets new access token
}
export default service