vue3+ts+vant json数据转树结构并去重

162 阅读1分钟

效果图

商品分类实现效果图.png

后端返回数据结构

{
"apistatus":200,
"msg":"成功",
"data":{
    "total":310,
    "categoryList":[
    {
        "firstCategoryId":5973,"firstCategoryName":"运动户外","
        secondCategoryId":5982,"secondCategoryName":"运动包/配件","
        thirdCategoryId":6386,"thirdCategoryName":"运动护具",
        "count":18
    },
    {
	"firstCategoryId":5973,
	"firstCategoryName":"运动户外",
	"secondCategoryId":5975,
	"secondCategoryName":"运动服饰",
	"thirdCategoryId":6108,
	"thirdCategoryName":"运动T恤",
	"count":16
	},
	{
	"firstCategoryId":5973,
	"firstCategoryName":"运动户外",
	"secondCategoryId":5975,
	"secondCategoryName":"运动服饰",
	"thirdCategoryId":6116,
	"thirdCategoryName":"运动风衣",
	"count":13
	},
	{
	"firstCategoryId":5903,
	"firstCategoryName":"日用百货",
	"secondCategoryId":5930,
	"secondCategoryName":"家纺",
	"thirdCategoryId":6322,
	"thirdCategoryName":"毛巾浴巾",
	"count":12
	,{
	"firstCategoryId":6523,
	"firstCategoryName":"粮油调味",
	"secondCategoryId":5960,
	"secondCategoryName":"粮油调味(1)",
	"thirdCategoryId":6052,
	"thirdCategoryName":"米面/面粉",
	"count":10
	},
	{"firstCategoryId":6523,
	"firstCategoryName":"粮油调味",
	"secondCategoryId":5960,
	"secondCategoryName":"粮油调味(1)",
	"thirdCategoryId":6308,
	"thirdCategoryName":"健康杂粮",
	"count":10
	},{
	"firstCategoryId":6523,
	"firstCategoryName":"粮油调味",
	"secondCategoryId":5960,
	"secondCategoryName":"粮油调味(1)",
	"thirdCategoryId":6047,"thirdCategoryName":
	"食用油","count":9
	},{
	"firstCategoryId":5973,
	"firstCategoryName":"运动户外",
	"secondCategoryId":5980,
	"secondCategoryName":"体育休闲",
	"thirdCategoryId":6388,
	"thirdCategoryName":"羽毛球",
	"count":8}
	,"errors":null,"success":true}

将数据转为树结构

let arrList = data.data.categoryList
let firstList = [
firstList = tabList.data.categoryList.reduce((pre, cur) => {
                debugger
                newObj[cur.firstCategoryId] ? '' : newObj[cur.firstCategoryId] = pre.push({
                    cateId: cur.firstCategoryId,
                    cateName: cur.firstCategoryName
                })
                return pre
            }, [])
let secondObj: any = {}
firstList.forEach((item: any) => {
                var secondList = tabList.data.categoryList.reduce((pre, cur) => {
                    if (cur.firstCategoryId === item.cateId) {
                        secondObj[cur.secondCategoryId] ? '' : secondObj[cur.secondCategoryId] =
                            pre.push({
                                cateId: cur.secondCategoryId,
                                cateName: cur.secondCategoryName
                            })
                    }
                    return pre
                }, [])
                item.children = [...secondList]
            })
let thirdObj: any = {}
firstList.forEach((item: any) => {
    item.children.forEach((secondItem: any) => {
        var thirdList = tabList.data.categoryList.reduce((pre, cur) => {
        if (cur.secondCategoryId === secondItem.cateId) {
                thirdObj[cur.thirdCategoryId] ? '' : thirdObj[cur
                                .thirdCategoryId] = pre.push({
                                cateId: cur.thirdCategoryId,
                                cateName: cur.thirdCategoryName
                            })
                        }
                        return pre
                    }, [])
                    secondItem.children = [...thirdList]
                })
            })
            tabList.data.firstList.unshift({
                cateName: '全部分类'
            })
    console.log('tabList.data.firstList:', tabList.data.firstList)

页面布局

<div class="classify">
        <div class="classify-ctn">
            <div class="classify-tab">
                <div class="tab-content">
                    <ul class="tab_left">
                        <li 
                            v-for="(firstCate, index) in tabList.data.firstList" 
                            :key="firstCate.cateId"
                            :class="index == $store.getters.activeInfo ? 'activeLi' : ''"
                            @click="changeTab(index)"
                            >
                            {{ firstCate.cateName }}
                        </li>
                    </ul>
                    <template v-for="(firstCate, index) in tabList.data.firstList" :key="index">
                        <div v-if="index == $store.getters.activeInfo" class="tab_right">
                            <van-cell :title="'全部 '+ firstCate.cateName" is-link :border="false" :clickable="false"
                                icon="location-o" class="all-cate" @click="toItem(firstCate.cateId, firstCate.cateName)">
                                <template #icon>
                                    <van-icon class-prefix="iconfont icon-fenleibiaoshi" color="#bf1c2f" />
                                </template>
                            </van-cell>
                            <van-row v-for="(secondCate) in firstCate.children" :key="secondCate.cateId">
                                <van-cell :title="secondCate.cateName" is-link :border="false" :clickable="false"
                                    @click="toItem(secondCate.cateId, secondCate.cateName)">
                                    <template #icon>
                                        <van-icon class-prefix="iconfont icon-fenleibiaoshi" color="#bf1c2f" />
                                    </template>
                                </van-cell>
                                <van-col v-for="(thirdCate) in secondCate.children" :key="thirdCate.cateId"
                                    class="line-text" @click="toItem(thirdCate.cateId, thirdCate.cateName)">
                                    {{ thirdCate.cateName }}
                                </van-col>
                            </van-row>
                        </div>
                    </template>
                </div>
            </div>
        </div>
    </div>

css样式

<style lang="less" scoped>
    .classify {

        margin-top: 5px;
        display: flex;
        justify-content: space-between;

        .classify-ctn {
            width: 100%;
            height: 100%;
            overflow: auto;
            color: #333;

            .classify-tab {
                width: 100%;
                height: calc(100% - 96px);
                overflow: scroll;

                .van-pull-refresh {
                    height: 100%;
                }

                .tab-content {
                    width: 100%;
                    height: 100%;
                    display: flex;
                    position: relative;
                    background: #fff;

                    .tab_left {
                        // position: absolute;
                        width: 130px;
                        height: 450px;
                        overflow-y: auto;
                        background: #F1F1F1;

                        >li {
                            width: 130px;
                            height: 46px;
                            line-height: 46px;
                            text-align: center;
                            font-size: 15px;
                            color: #999;
                            overflow: hidden;
                            text-overflow: ellipsis;
                            white-space: nowrap;
                        }

                        .activeLi {
                            background: #fff;
                            color: #BF1C2F;
                            font-size: 16px;
                            font-weight: bold;
                        }
                    }

                    .tab_right {
                        position: absolute;
                        left: 130px;
                        height: 100%;
                        width: calc(100vw - 130px);
                        overflow-y: auto;
                        background: #f6f6f6;

                        >div>div:nth-child(1) {
                            margin-top: 10px;
                        }

                        .all-cate {
                            width: calc(100% - 20px);
                            margin: 10px 10px 0 10px;
                            display: flex;
                            justify-content: space-evenly;
                            border-radius: 8px;
                        }

                        .van-cell {
                            padding-left: 5px;
                            font-size: 15px;
                            color: #333;
                            font-weight: bold;
                        }

                        .van-row {
                            display: flex;
                            justify-content: space-between;
                            background: #FFF;
                            margin: 10px;
                            padding-bottom: 5px;
                            border-radius: 8px;
                        }

                        .van-col {
                            width: calc(50% - 15px);
                            height: 40px;
                            line-height: 40px;
                            font-size: 14px;
                            color: #333;
                            border-radius: 4px;
                            padding: 0 10px;
                            background: #F3F3F3;
                            margin: 5px 0;
                        }

                        .van-col:nth-child(even) {
                            margin-left: 10px;
                        }

                        .van-col:nth-child(odd) {
                            margin-right: 10px;
                        }
                    }
                }
            }
        }
    }
</style>