我在为公司的旧项目添加功能的时候遇到了这么一个问题,由于旧项目使用的是比较旧的 jquery框架,而我新加的功能模块使用的是vue + elementui,在使用element 的级联组件的时候发现旧有的接口返回的地址数据都是平铺的,这就跟element 的组建的默认的数据嵌套结构不一致了,因此前端这边就需要做一下数据结构的转换。
一开始我的想法是使用递归的方式一遍一遍的遍历数组然后重组成嵌套的对象,后来我发现这样的遍历3000多条数据效率太低了,很容易就卡死的页面。而经过了后端大佬的额指点后换了另一种方法,效率马上就翻了好几倍。
数据格式
[{
"name": "北京市",
"pId": "0",
"id": "110000"
}, {
"name": "北京城区",
"pId": "110000",
"id": "110100"
}, {
"name": "东城区",
"pId": "110100",
"id": "110101"
}]
js逻辑
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
options:[]
},
created() {
let obj = {}, newarr = []
axios.get('./dy.json').then(res=>{
let data = res.data
console.log(data)
// 后端的数据默认规定第一层的数据pid为0
for (let i = 0; i < data.length; i++) {
if(data[i].pId == "0") { // 一地步就是先把第一层的数据单独拿出来
newarr.push(data[i])
}
obj[data[i].id] = data[i] // 以id 为属性名,吧数组转换为对象,方便下面再次遍历的时候吧数据挂到上层的children 中
}
for (let i = 0; i < data.length; i++) {
let pid = data[i].pId;
if(pid in obj) { // 排除第一层的数据,通过当前数据的pid 找到obj 中的自己的上级
if(!obj[pid].hasOwnProperty('children')) { //为自己的上级添加一个children 数组用于存放与自身同组的成员数据
obj[pid].children = []
}
obj[pid].children.push(data[i]) // 入列
}
}
obj = null // 清空对象内存
this.options = JSON.parse(JSON.stringify(newarr).replaceAll('name', 'label').replaceAll('id','value'))
})
}
})
完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.0/theme-chalk/index.css" rel="stylesheet">
<style type="text/css">
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.0/index.js"></script>
</head>
<body>
<div id="app">
{{ message }}
<el-cascader :options="options" :show-all-levels="false"></el-cascader>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
options:[]
},
created() {
let obj = {}, newarr = []
axios.get('./dy.json').then(res=>{
let data = res.data
for (let i = 0; i < data.length; i++) {
if(data[i].pId == "0") {
newarr.push(data[i])
}
obj[data[i].id] = data[i]
}
for (let i = 0; i < data.length; i++) {
let pid = data[i].pId;
if(pid in obj) {
if(!obj[pid].hasOwnProperty('children')) {
obj[pid].children = []
}
obj[pid].children.push(data[i])
}
}
obj = null
this.options = JSON.parse(JSON.stringify(newarr).replaceAll('name', 'label').replaceAll('id','value'))
})
}
})
</script>
</html>