我在為公司的舊項目添加功能的時候遇到了這么一個問題畦木,由于舊項目使用的是比較舊的 jquery框架,而我新加的功能模塊使用的是vue + elementui何暇,在使用element 的級聯(lián)組件的時候發(fā)現(xiàn)舊有的接口返回的地址數(shù)據(jù)都是平鋪的容客,這就跟element 的組建的默認(rèn)的數(shù)據(jù)嵌套結(jié)構(gòu)不一致了,因此前端這邊就需要做一下數(shù)據(jù)結(jié)構(gòu)的轉(zhuǎn)換黔姜。
一開始我的想法是使用遞歸的方式一遍一遍的遍歷數(shù)組然后重組成嵌套的對象,后來我發(fā)現(xiàn)這樣的遍歷3000多條數(shù)據(jù)效率太低了蒂萎,很容易就卡死的頁面。而經(jīng)過了后端大佬的額指點后換了另一種方法淮椰,效率馬上就翻了好幾倍五慈。
數(shù)據(jù)格式
[{
"name": "北京市",
"pId": "0",
"id": "110000"
}, {
"name": "北京城區(qū)",
"pId": "110000",
"id": "110100"
}, {
"name": "東城區(qū)",
"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)
// 后端的數(shù)據(jù)默認(rèn)規(guī)定第一層的數(shù)據(jù)pid為0
for (let i = 0; i < data.length; i++) {
if(data[i].pId == "0") { // 一地步就是先把第一層的數(shù)據(jù)單獨拿出來
newarr.push(data[i])
}
obj[data[i].id] = data[i] // 以id 為屬性名,吧數(shù)組轉(zhuǎn)換為對象主穗,方便下面再次遍歷的時候吧數(shù)據(jù)掛到上層的children 中
}
for (let i = 0; i < data.length; i++) {
let pid = data[i].pId;
if(pid in obj) { // 排除第一層的數(shù)據(jù)泻拦,通過當(dāng)前數(shù)據(jù)的pid 找到obj 中的自己的上級
if(!obj[pid].hasOwnProperty('children')) { //為自己的上級添加一個children 數(shù)組用于存放與自身同組的成員數(shù)據(jù)
obj[pid].children = []
}
obj[pid].children.push(data[i]) // 入列
}
}
obj = null // 清空對象內(nèi)存
this.options = JSON.parse(JSON.stringify(newarr).replaceAll('name', 'label').replaceAll('id','value'))
})
}
})
完整代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link 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>