左右联动

发布于 2024-09-23  421 次阅读


<template>
    <view class="silk_box">
        <view class="silk_top">
            <view class="top_left">
                <image src="../../static/silk_bg.png" mode=""></image>
            </view>
            <view class="top_right">
                会员可使用积分抵扣或直接支付费用
            </view>
        </view>
        <view class="silk_content">
            <view class="content_left">
                <scroll-view scroll-y="true" class="left_scroll" :style="{ 'height':scrollHeight + 'px' }"
                    :scroll-with-animation="false">
                    <view @click="leftTap(i)" :class="['left_info', i==leftIndex? 'left_active':'' ]" v-for="i in 20" :key="i" :id="'left-'+i">
                        深睡配方
                    </view>
                </scroll-view>

            </view>
            <view class="content_right">
                <scroll-view scroll-y="true" :style="{ 'height':scrollHeight + 'px' }" @scroll="mainScroll"
                    :scroll-into-view="scrollInto" :scroll-with-animation="false">
                    <view class="right_box" v-for="i in 20" :key="i" :id="'item-'+i">
                        <view class="right_title">
                            标题{{i}}
                        </view>
                        <view class="right_info">

                            <view class="right_content" v-for="j in 10" :key="j">
                                <view class="good_img">
                                    <image src="../../static/silk_sleep.png" mode=""></image>
                                </view>
                                <view class="good_right">
                                    <view class="good_title">
                                        沐浴套装{{i}}
                                    </view>
                                    <view class="good_info">
                                        1个蒸不二联名沐浴套装+2个足浴包,足浴包可以带回家足浴包可以足浴包可以带回家足浴包可以
                                    </view>
                                    <view class="good_bottom">
                                        <view class="price_box">
                                            <view class="new_price">
                                                ¥<text>88.00</text>/套
                                            </view>
                                            <view class="old_price">
                                                ¥108
                                            </view>
                                        </view>
                                        <view class="operate_box">
                                            <view class="operate_icon">
                                                <image src="../../static/silk_plus.png" mode=""></image>
                                            </view>
                                            <view class="operate_num">
                                                1
                                            </view>
                                            <view class="operate_icon">
                                                <image src="../../static/silk_add.png" mode=""></image>
                                            </view>
                                        </view>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view class="fill_last" :style="{ 'height':fillHeight + 'px' }"></view>
                </scroll-view>
            </view>
        </view>
        <view class="silk_button">
            <view class="button_left">
                <view class="button_price">
                    ¥<text>88.00</text>
                </view>
                <view class="button_bill" @click="billClick">
                    账单明细
                </view>
            </view>
            <view class="button_right">
                选定服务(0)
            </view>
        </view>

        <!-- 账单明细弹窗 -->
        <Mask v-if="billShow" :maskShow="billShow" @close="billClose">
            <view class="bill_box">
                <view class="bill_top">
                    <view class="bill_title">
                        温创锦囊WENPLUS服务明细
                    </view>
                    <view class="discount_icon" @click="billClose">
                        <!-- <u-icon name="close" color="#000000" size="24"></u-icon> -->
                        <image src="../../static/discount_close.png" mode=""></image>
                    </view>
                </view>
                <view class="bill_content">
                    <view class="bill_flex" v-for=" i in 10">
                        <view class="flex_info">
                            沐浴套装 ×1
                        </view>
                        <view class="flex_info">
                            ¥88.00
                        </view>
                    </view>
                </view>
            </view>

        </Mask>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                scrollHeight: 400, // 默认高度
                scrollTopSize: 0, // 默认顶部高度
                fillHeight: 0, // 填充高度,用于最后一项低于滚动区域时使用
                topArr: [], // 左侧列表元素
                leftIndex: 0, // 点击切换存储的下标
                scrollInto: '', // 左侧定位
                cateData: [],
                cateName: [],
                listData: [],
                billShow: false,
                shopId: '',
                categoryList: []

            };
        },
        onLoad(options) {
            this.shopId = options.shopId || ''
            this.onRightListFetch()
            this.getServiceGoodsCategory()
        },
        methods: {
            async getServiceGoodsCategory() {
                let data = {
                    shopId: this.shopId
                }
                const res = await this.Http.indexService.getServiceGoodsCategory(data)
                console.log(res,"锦囊分类");
                this.categoryList = res?.retdata?.categoryList || []
            },
            async getServiceGoodsList(){
                let data = {
                    shopId: this.shopId
                }
                const res = await this.Http.indexService.getServiceGoodsCategory(data)
                console.log(res,"锦囊列表");
            },
            billClose() {
                this.billShow = false
            },
            billClick() {
                this.billShow = !this.billShow
            },
            /* 初始化滚动区域 */
            initScrollView() {
                return new Promise((resolve, reject) => {
                    let view = uni.createSelectorQuery().select('.silk_content');
                    view.boundingClientRect(res => {
                        this.scrollTopSize = res.top;
                        this.scrollHeight = res.height;
                        setTimeout(() => {
                            resolve();
                        }, 100);
                    }).exec();
                });
            },
            // 获取右边数据
            async onRightListFetch() {
                this.nextTick(() => {
                    this.getElementTop()
                    this.initScrollView()
                })
                // const res = await this.store.dispatch("tool/getToolList", {

                // });
                // if ([100].includes(res.code)) {
                //  this.listTotal = res.result.tltal
                //  this.listData = res.result.data || []
                //  let map = new Map();
                //  for (let item of this.listData) {
                //      map.set(item.cateId, item);
                //  }
                //  this.cateName = [...map.values()].sort((a, b) => {
                //      return a.cateId - b.cateId
                //  });
                //  this.nextTick(() => {
                //      this.getElementTop()
                //      this.initScrollView()
                //  })
                // } else {
                //  this.toast(res.msg);
                // }
            },
            // 获取左边数据
            async onLeftListFetch() {
                const res = await this.store.dispatch('tool/getCateList')
                if ([100].includes(res.code)) {
                    this.cateTotal = res.result.total
                    this.cateData = res.result.data.sort((a, b) => {
                        return a.id - b.id
                    }) || []
                    this.loading = false
                } else {
                    this.toast(res.msg)
                }
            },
            /* 获取元素顶部信息 */
            getElementTop() {
                new Promise((resolve, reject) => {
                    let view = uni.createSelectorQuery().selectAll('.right_box');
                    view.boundingClientRect(data => {
                        resolve(data);
                    }).exec();
                }).then((res) => {
                    console.log('res', res);
                    let topArr = res.map((item) => {
                        return item.top - this.scrollTopSize; /* 减去滚动容器距离顶部的距离 */
                    });
                    this.topArr = topArr;
                    /* 获取最后一项的高度,设置填充高度。判断和填充时做了 +-20 的操作,是为了滚动时更好的定位 */
                    let last = res[res.length - 1].height;
                    if (last - 20 < this.scrollHeight) {
                        this.fillHeight = this.scrollHeight - last + 20;
                    }
                });
            },
            /* 主区域滚动监听 */
            mainScroll(e) {
                // 节流方法
                clearTimeout(this.mainThrottle);
                this.mainThrottle = setTimeout(() => {
                    scrollFn();
                }, 10);
                let scrollFn = () => {
                    let top = e.detail.scrollTop;
                    let index = 0;
                    /* 查找当前滚动距离 */
                    this.topArr.forEach((item, id) => {
                        if ((top + 2) >= item) {
                            index = id;
                            this.leftIndex = (index < 0 ? 0 : index);
                        }
                    })
                }
            },
            /* 左侧导航点击 */
            leftTap(e) {
                this.leftIndex = e
                this.scrollInto = "item-" + e;
            }

        }
    }
</script>
<style>
    page {
        background: #F5F7FA;
    }
</style>
<style lang="scss" scoped>
    .silk_box {
        display: flex;
        flex-direction: column;
        height: 100vh;

        .silk_top {
            background: #ffffff;
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 32rpx 80rpx 32rpx 28rpx;
            box-sizing: border-box;
            margin-bottom: 16rpx;

            .top_left {
                width: 192rpx;
                height: 82rpx;

                image {
                    width: 100%;
                    height: 100%;
                }
            }

            .top_right {
                font-family: PingFangSC, PingFang SC;
                font-weight: 400;
                font-size: 24rpx;
                color: #1E2226;
            }
        }

        .silk_content {
            flex: 1;
            overflow: hidden;
            display: flex;
            background: #FFFFFF;

            .content_left {
                width: 168rpx;
                height: 100%;
                background: #FFFFFF;
                border-right: 1px solid #E9ECF0;

                .left_scroll {
                    height: 100%;
                }

                .left_info {
                    height: 92rpx;
                    background: #F0F2F5;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    font-family: PingFangSC, PingFang SC;
                    font-weight: 400;
                    font-size: 28rpx;
                    color: #1E2226;
                }
                .left_active {
                    background: #FFFFFF !important;
                    color: #A6936F !important;
                }
            }

            .content_right {
                flex: 1;
                // padding: 32rpx 28rpx;
                box-sizing: border-box;
                .right_box {

                    margin-bottom: 12rpx;
                    .right_title {
                        font-family: PingFangSC, PingFang SC;
                        font-weight: 500;
                        font-size: 28rpx;
                        color: #1E2226;
                        padding: 32rpx 28rpx 16rpx 28rpx;
                        box-sizing: border-box;
                        position: sticky;
                        top: 0;
                        z-index: 19;
                        background: #FFFFFF;
                    }
                    .right_info {
                        padding: 0 28rpx 1rpx 28rpx;
                        box-sizing: border-box;

                        .right_content {
                            display: flex;
                            align-items: center;
                            margin-bottom: 24rpx;
                            .good_img {
                                width: 152rpx;
                                height: 152rpx;
                                background: #807155;
                                border-radius: 8rpx;
                                display: flex;
                                align-items: center;
                                justify-content: center;
                                image {
                                    width: 80rpx;
                                    height: 80rpx;
                                }
                            }
                            .good_right {
                                margin-left: 16rpx;
                                flex: 1;
                                .good_title {
                                    font-family: PingFangSC, PingFang SC;
                                    font-weight: bold;
                                    font-size: 24rpx;
                                    color: #1E2226;
                                }
                                .good_info {
                                    font-family: PingFangSC, PingFang SC;
                                    font-weight: 400;
                                    font-size: 20rpx;
                                    color: #8A9099;
                                    margin-top: 6rpx;
                                    overflow: hidden;
                                    text-overflow: ellipsis;
                                    display: -webkit-box;
                                    -webkit-line-clamp: 2;
                                    -webkit-box-orient: vertical;
                                    word-break: break-all;
                                }
                                .good_bottom {
                                    margin-top: 14rpx;
                                    display: flex;
                                    align-items: center;
                                    justify-content: space-between;
                                    .price_box {
                                        display: flex;
                                        align-items: flex-end;
                                        .new_price {
                                            font-family: PingFangSC, PingFang SC;
                                            font-weight: 400;
                                            font-size: 20rpx;
                                            color: #E62600;
                                            text {
                                                font-size: 30rpx;
                                            }
                                        }
                                        .old_price {
                                            font-family: PingFangSC, PingFang SC;
                                            font-weight: 400;
                                            font-size: 20rpx;
                                            color: #B6BABF;
                                            text-decoration: line-through;
                                            margin-left: 8rpx;
                                        }
                                    }
                                    .operate_box {
                                        display: flex;
                                        align-items: center;
                                        .operate_icon {
                                            display: flex;
                                            align-items: center;
                                            justify-content: center;
                                            width: 36rpx;
                                            height: 36rpx;
                                            background: #C9B286;
                                            border-radius: 50%;
                                            image {
                                                width: 16rpx;
                                                height: 16rpx;
                                            }
                                        }
                                        .operate_num {
                                            font-family: PingFangSC, PingFang SC;
                                            font-weight: 400;
                                            font-size: 28rpx;
                                            color: #1E2226;
                                            margin: 0 20rpx;
                                        }
                                    }
                                }
                            }

                        }
                    }
                }
            }
        }
        .silk_button {
            background: #ffffff;
            padding: 24rpx 32rpx 24rpx 28rpx;
            padding-bottom: 24rpx + constant(safe-area-inset-bottom);
            /*兼容 IOS<11.2*/
            padding-bottom: 24rpx + env(safe-area-inset-bottom);
            display: flex;
            align-items: center;
            justify-content: space-between;
            z-index: 9999;
            .button_left {
                display: flex;
                align-items: center;
                .button_price {
                    font-family: PingFangSC, PingFang SC;
                    font-weight: 600;
                    font-size: 28rpx;
                    color: #1E2226;
                    text {
                        font-size: 44rpx;
                    }
                }
                .button_bill {
                    font-family: PingFangSC, PingFang SC;
                    font-weight: 400;
                    font-size: 24rpx;
                    color: #C9B286;
                    margin-left: 16rpx;
                }
            }
            .button_right {
                width: 344rpx;
                height: 88rpx;
                background: #C9B286;
                border-radius: 16rpx;
                display: flex;
                align-items: center;
                justify-content: center;
                font-family: PingFangSC, PingFang SC;
                font-weight: 500;
                font-size: 32rpx;
                color: #FFFFFF;
            }
        }
        .bill_box {
            position: fixed;
            bottom: 94rpx;
            width: 750rpx;
            background: #FFFFFF;
            border-radius: 24rpx 24rpx 0 0;
            padding: 30rpx;
            box-sizing: border-box;
            height: 60%;
            padding-bottom: calc(constant(safe-area-inset-bottom) + 54rpx);
            /*兼容 IOS<11.2*/
            padding-bottom: calc(env(safe-area-inset-bottom) + 54rpx);
            overflow: hidden;
            display: flex;
            flex-direction: column;

            .bill_top {
                display: flex;
                align-items: center;
                justify-content: space-between;

                /*兼容 IOS>11.2*/
                .discount_icon {
                    // position: absolute;
                    // top: 36rpx;
                    // right: 38rpx;
                    image {
                        width: 36rpx;
                        height: 36rpx;
                    }
                }

                .bill_title {
                    // text-align: center;
                    font-family: PingFangSC, PingFang SC;
                    font-weight: bold;
                    font-size: 32rpx;
                    color: #1E2226;
                    flex: 1;
                    text-align: center;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    display: -webkit-box;
                    -webkit-line-clamp: 1;
                    -webkit-box-orient: vertical;
                    word-break: break-all;
                }
            }
            .bill_content {
                flex: 1;
                overflow: auto;
                margin-top: 54rpx;
                .bill_flex {
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                    font-family: PingFangSC, PingFang SC;
                    font-weight: 400;
                    font-size: 28rpx;
                    color: #1E2226;
                    margin-bottom: 24rpx;
                }
            }
        }
    }
</style>


只会写bug的bugming