小程序左侧菜单

小程序左侧菜单

 

 

<template>
    <view class="classify-container">
        <view class="container-header">
            <swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000"
                indicator-color="rgba(255,255,255,0.5)" indicator-active-color="#fff">
                <swiper-item v-for='(item,index) in 8' :key='index'>
                    <view class="swiper-item">
                        <image class='swiper-img' src="https://yanxuan.nosdn.127.net/static-union/16805163298d320c.jpg"
                            mode="aspectFill"></image>
                    </view>
                </swiper-item>
            </swiper>
        </view>
        <view class="container" :style="'height:'+rightScrollMain+'px;'">
            <view class="main" :style="'height:'+rightScrollMain+'px;'">
                <view class="main_left">
                    <view v-for="(item,index) in allData" :key="id" class="left_item"
                        :class="mainLeftIndex == index ? 'left_item_active' : ''" @click="mainLeftItemTap(index)">
                        {{item.name}}
                    </view>
                </view>
                <scroll-view class="main_right" scroll-y scroll-with-animation :style="'height:'+rightScrollMain+'px;'"
                    :scroll-into-view="intoViewId" @scroll="rightScroll">
                    <view class="main_right_box" v-for="(item,index) in allData" :key="item.id"
                        :id="'scroll' + item.id">
                        <view class="right_tap">
                            {{item.name}}
                        </view>
                        <view class="right_item" v-for="(item,index) in item.list" :key="listId">
                            <view class="item_img_box">
                                <image class="item_img" :src="item.phoneImg" mode="" />
                            </view>
                            <view class="item_right">
                                <view class="right_title">{{item.title}}</view>
                                <view class="right_price">
                                    ¥{{item.price}}
                                </view>
                                <view class="right_bottom">
                                    <view class="bottom_left">
                                        5折
                                    </view>
                                    <view class="bottom_right">+</view>
                                </view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                allData: [{
                        name: 'Xiaomi手机',
                        id: 1111,
                        list: [{
                                title: 'Xiaomi 13',
                                price: 4999,
                                listId: 1523,
                                phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202211292343_1fb2e2ce696643e2e9e863f69cdaf781.png'
                            },
                            {
                                title: 'Xiaomi 13 限量定制色',
                                price: 3999,
                                listId: 1523,
                                phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202211292351_92aba2c69123166a74ba2e2b525b1ae2.png'
                            },
                            {
                                title: 'Xiaomi 12S Ultra',
                                price: 4999,
                                listId: 1523,
                                phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202207011810_86ad513472d1423a3fdec8d7d5107038.png'
                            }, {
                                title: 'Xiaomi 12S Pro',
                                price: 5999,
                                listId: 23,
                                phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202207012000_0b9df066c110f201154013ac373df1d9.png'
                            }, {
                                title: 'Xiaomi 12S',
                                price: 4099,
                                listId: 14,
                                phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202211292351_92aba2c69123166a74ba2e2b525b1ae2.png'
                            }, {
                                title: 'Xiaomi 12 Pro 天玑版',
                                price: 4199,
                                listId: 13,
                                phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/eac4850d9dbc5305b1298b8c1c686c17.png'
                            }, {
                                title: 'Xiaomi 12 Pro',
                                price: 3199,
                                listId: 112,
                                phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/bec639601906ed7649970c6ab311f992.png'
                            }
                        ]
                    },
                    {
                        name: 'Redmi手机',
                        id: 2222,
                        list: [{
                            title: 'Redmi K60 Pro',
                            price: 3299,
                            listId: 15223,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202212261456_d20c10733b97c9395bd05c97092a4120.png'
                        }, {
                            title: 'Redmi K60',
                            price: 2499,
                            listId: 223,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202212261429_eb1f972370482850735ca16e2121dd08.png'
                        }, {
                            title: 'Redmi K50 Pro',
                            price: 2699,
                            listId: 124,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/bfe68c63caca6622d1673efa7d7e7a7d.png'
                        }, {
                            title: 'Redmi K50',
                            price: 2099,
                            listId: 133,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/268eb39e48af6bb86e448e143a119eea.png'
                        }, {
                            title: 'Redmi K40S',
                            price: 100,
                            listId: 13132,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/8705d355125196baa7f8c2df87936290.png'
                        }]
                    },
                    {
                        name: '游戏手机',
                        id: 3333,
                        list: [{
                            title: '黑鲨5/黑鲨5 高能版',
                            price: 2599,
                            listId: 15233,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/ef619ad3807b50ab8f6d12656fcc3721.png'
                        }, {
                            title: '黑鲨5 Pro',
                            price: 4199,
                            listId: 233,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/29d255503783b6838beee713dd5630ec.png'
                        }, {
                            title: '黑鲨5 RS',
                            price: 2799,
                            listId: 144,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f77f2b5c0a09d53f739e1cffe3394ca3.png'
                        }, {
                            title: 'K50 电竞版',
                            price: 3299,
                            listId: 135,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f5d5806d6807671fd2a28d9a944b5358.png'
                        }, {
                            title: '黑鲨5/黑鲨5 高能版',
                            price: 2599,
                            listId: 1124,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f77f2b5c0a09d53f739e1cffe3394ca3.png'
                        }, {
                            title: '黑鲨5 Pro',
                            price: 4199,
                            listId: 233,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f77f2b5c0a09d53f739e1cffe3394ca3.png'
                        }, {
                            title: '黑鲨5 RS',
                            price: 4199,
                            listId: 233,
                            phoneImg: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f77f2b5c0a09d53f739e1cffe3394ca3.png'
                        }]
                    }
                ], // 所有产品数据
                mainLeftIndex: 0, // 左边高亮下标
                intoViewId: null, // 滚动到指定位置id
                mainDistance: 0, // 存放滚动的高度
                heightArr: [], // 存放每个类目的高度
                heightNumber: 0, // 一次递增的累积高度
                windowHeight: 0,
                rightScrollMain: 0,
            }
        },
        methods: {
            // 获取所有商品数据
            getProductAllData() {
                let heightArr = []
                let heightNumber = 0 // 一次递增的累积高度
                const _dataLength = this.allData.length // 类目数量
                for (let i = 0; i < _dataLength; i++) {
                    // 50 为类目的标题高度 200 为每个产品的高度
                    let height = 50 + (200 * this.allData[i].list.length)
                    // 我们与上一个高度相加
                    heightNumber += height
                    // +=  等于  heightNumber = heightNumber + height
                    // 因为我们设置的是rpx,我们需要将rpx转成px
                    heightArr.push(this.rpxTopx(heightNumber))
                }
                this.heightArr = heightArr
            },
            // rpx转px
            rpxTopx(rpx) {
                const screenWidth = uni.getSystemInfoSync().screenWidth
                return (screenWidth * Number.parseInt(rpx)) / 750
            },
            // 导航左边点击
            mainLeftItemTap(idx) {
                this.mainLeftIndex = idx
                this.intoViewId = 'scroll' + this.allData[idx].id
            },
            // 右侧滚动触发
            rightScroll(e) {
                const {
                    scrollTop
                } = e.detail
                let _index = this.mainLeftIndex // 左边的高亮下标
                if (scrollTop > this.mainDistance) { // 如果大于mainDistance表示用户上滑
                    if (_index + 1 < this.heightArr.length && scrollTop >= this.heightArr[_index]) {
                        this.mainLeftIndex = _index + 1
                    }
                } else { // 用户下滑
                    // 先判断下标-1要大于0(左边标签第一个时就不减了)
                    // 再判断用户滚动高度是否小于下标上一个总高度,如果小于就-1
                    if (_index - 1 >= 0 && scrollTop < this.heightArr[_index - 1]) {
                        this.mainLeftIndex = _index - 1
                    }
                }
                this.mainDistance = scrollTop // 最后我们才赋值
            },
        },
        onLoad() {
            this.getProductAllData();
            uni.getSystemInfo({
                success: (res) => {
                    console.log(res.windowHeight); // 可使用窗口高度,不包含导航栏
                    this.windowHeight = res.windowHeight
                }
            })
        },
        onReady() {
            const query = uni.createSelectorQuery().in(this);
            query.select('.container-header').boundingClientRect(data => {
                this.rightScrollMain = this.windowHeight - data.height
            }).exec();
        }
    }
</script>
<style lang="scss">
    .classify-container {
        .container-header {
            swiper {
                width: 100%;
                height: 360rpx;
            }

            .swiper-img {
                width: 100%;
                height: 360rpx;
            }
        }
    }

    .container {
        // borderColor: rgba(230, 224, 224, 0.733);
        border-radius: 10rpx 10rpx 0 0;
        margin-top: -10rpx;
        background-color: #fff;
        font-size: 32rpx;

        .cont_title {
            width: 140rpx;
            height: 80rpx;
            line-height: 80rpx;
            text-align: center;
            border-bottom: 6rpx solid #000;
            margin: 0 auto;
            font-weight: 500;
            font-size: 36rpx;
            box-sizing: border-box;
        }

        .cont_info {
            width: 100%;
            display: flex;
            justify-content: space-between;
            padding: 0 20rpx;
            box-sizing: border-box;
            height: 80rpx;
            line-height: 80rpx;
            border-bottom: 2rpx solid var(--borderColor);

            .info_left {
                color: gray;
            }

            .info_right {
                color: rgb(50, 36, 247);
                height: 100%;
                line-height: 80rpx;

                .right_img {
                    width: 30rpx;
                    height: 30rpx;
                    margin-top: -6rpx;
                    vertical-align: middle;
                }
            }
        }

        .main {
            width: 100%;
            // height: calc(100vh - 80rpx - 80rpx - 300rpx + 10rpx);
            display: flex;
            font-size: 32rpx;

            .main_left {
                width: 200rpx;
                border-right: 2rpx solid var(--borderColor);
                color: gray;
                height: 100%;

                .left_item {
                    width: 100%;
                    height: 120rpx;
                    line-height: 120rpx;
                    padding: 20rpx;
                    box-sizing: border-box;
                    font-size: 24rpx // overflow: hidden;
                }

                .left_item_active {
                    color: #000;
                    font-weight: 500;
                    position: relative;

                    &::before {
                        content: '';
                        position: absolute;
                        width: 10rpx;
                        height: 40rpx;
                        background-color: red;
                        top: 50%;
                        left: 0;
                        transform: translateX(-50%);
                    }
                }
            }

            .main_right {
                flex: 1;
                padding: 10rpx;
                box-sizing: border-box;

                .right_tap {
                    width: 100%;
                    height: 50rpx;
                    line-height: 50rpx;
                    font-weight: 700;
                    font-size: 30rpx;
                    position: sticky;
                    top: 0;
                    background-color: #fff;
                    z-index: 2;
                }

                .right_item {
                    display: flex;
                    font-size: 36rpx;

                    .item_img_box {
                        width: 200rpx;
                        height: 200rpx;
                        padding: 10rpx;
                        box-sizing: border-box;
                        flex-shrink: 0;

                        .item_img {
                            width: 100%;
                            height: 100%;
                        }
                    }

                    .item_right {
                        display: flex;
                        flex-direction: column;
                        justify-content: space-between;
                        padding: 10rpx;
                        box-sizing: border-box;

                        .right_title {
                            font-weight: 500;
                            font-size: 26rpx;
                        }

                        .right_price {
                            color: rgb(226, 51, 51);
                            font-weight: 500;
                        }

                        .right_bottom {
                            display: flex;
                            justify-content: space-between;
                            align-items: center;
                            width: 300rpx;

                            .bottom_left {
                                border: 3rpx solid red;
                                font-size: 24rpx;
                                color: red;
                                height: 30rpx;
                                line-height: 30rpx;
                                padding: 0 6rpx;
                            }

                            .bottom_right {
                                background-color: red;
                                color: #fff;
                                border-radius: 6rpx;
                                width: 40rpx;
                                height: 40rpx;
                                line-height: 34rpx;
                                text-align: center;
                            }
                        }
                    }
                }
            }
        }
    }
</style>

 

 

 

posted @ 2025-02-24 08:40  慕容冰菡  阅读(21)  评论(0)    收藏  举报