小程序楼梯效果

用了wepy组件 , 左右两边 分别是一个组件  (上代码了)  

里面的域名是线上域名   用了sass  需要下载,拉走代码 直接出效果 

1. 先上左边的组件  

<style lang="scss">
    page{
        height: 100%;
    }
    ::-webkit-scrollbar{
        width: 0;
        display: none;
    }
    .scroll_nav{
        padding-bottom: 200rpx;
        &_wrap{
            height: 100%;
            background: #fff;

        }
        &_items{
            height: 100rpx;
            line-height: 100rpx;
            text-align: center;
            font-size: 30rpx;
            color: #000;
            border-bottom: 1px solid #f4f6f8;
            &_active{
                color: #ca0707;
            }
        }

    }
</style>

<template>
    <scroll-view class="scroll_nav_wrap" scroll-y="true" scroll-top="{{navScrollTop}}" scroll-with-animation="true">

      <view class="scroll_nav">
            <repeat for="{{navDeails}}">
                <view class="scroll_nav_items {{item.id == selectedId ? 'scroll_nav_items_active' : ''}}" id="{{item.id}}" data-index="{{index}}" @tap="selectedFn">{{item.name}}</view>
            </repeat>
        </view>
    </scroll-view>

</template>

<script>

    import wepy from 'wepy'

    export default class ScrollNav extends wepy.component {
        props = {

        }
        data = {
            currentIndex: 0
        }
        props = {
            navDeails: {
                type: Array,
                coerce: (res) => {
                    return res
                }
            },
            selectedId:{
                type: [Number, String],
                coerce: (res) => {
                    return res
                }
            },
            navScrollTop: {
                type: [Number, String],
                coerce: res => res
            }
        }
        methods = {
            selectedFn(e){
                this.selectedId = e.currentTarget.id
                this.currentIndex = e.currentTarget.dataset.index
                this.$emit('change', this.currentIndex, this.selectedId)
            }
        }

    }
</script>

2. 右边的组件 
<style lang="scss">
    .scroll_view{
        &_wrap{
            height: 100%;
            background: #fff;
            position: relative;
        }
        &_items{
            min-height: 120rpx;
            &_tit{
                height: 58rpx;
                view{
                    font-size: 30rpx;
                    font-weight: bold;
                    line-height: 58rpx;
                    padding-left: 1em;
                    border-bottom: 1px solid #eee;
                }
                
            }
            // .tit_position{
            //     view{
            //         width: 100%;
            //         position: absolute;
            //         left: 0; top: 0;
            //     }
            // }
            &_children{
                width: 100%;
                padding: 34rpx 14rpx;
                border-bottom: 1px solid #eee;
                box-sizing: border-box;
                display: flex;
                &_img{
                    width: 160rpx;
                    height: 160rpx;
                    flex-shrink: 0;
                    background: {
                        size: cover;
                        repeat: no-repeat;
                        position: center center;
                    }
                }
                &_context{
                    margin-left: 16rpx;
                    font-size: 30rpx;
                    position: relative;
                    .name{
                        font-size: 30rpx;
                        overflow: hidden;
                        -webkit-line-clamp: 1;
                        white-space: normal;
                        display: -webkit-box;
                        -webkit-box-orient: vertical;
                        box-sizing: border-box;
                    }
                    .price_wrap{
                        position: absolute;
                        bottom: 0; left: 0;
                    }
                }
            }
        }
    }
</style>

<template>

    <scroll-view class="scroll_view_wrap" scroll-y="true" scroll-top="{{scrollTop}}" scroll-with-animation="true" @scroll="scrollFn">
        <repeat for="{{viewDeails}}">
            <view class="scroll_view_items">
                <view class="scroll_view_items_tit {{inx[index] == positionIndex ? 'tit_position' : ''}}">
                    <view>
                        {{item.name}}
                    </view>
                </view>
                <repeat for="{{item.children}}" item="i">
                    <view class="scroll_view_items_children" data-id="{{i.id}}" @tap="goTo">
                        <view class="scroll_view_items_children_img" style="background-image: url({{i.thumb}})"></view>
                        <view class="scroll_view_items_children_context">
                            <view class="name">{{i.name}}</view>
                            <view class="price_wrap">
                                <text class="price">{{i.price}}</text>
                            </view>
                        </view>
                    </view>
                </repeat>
            </view>
        </repeat>
    </scroll-view>

</template>

<script>

    import wepy from 'wepy'

    export default class ScrollView extends wepy.component {
        props = {
            viewDeails: {},
            scrollTop: {
                type: [Number, String],
                coerce: res => res
            },
            titleTop: {
                type: Array,
                coerce: res => res
            }
        }
        data = {
            positionIndex: 0,
            inx: {}
        }
        watch = {
            viewDeails(newVal){
                let index = 0
                this.inx = {}
                Object.keys(newVal).forEach( (item, index) => {
                    this.inx[item] = index
                })
                this.$apply()
            }
        }
        methods = {
            scrollFn(e){
                let selfTop = e.detail.scrollTop
                this.positionIndex = this.getScrollTopIndex(selfTop)
                this.$emit('change', this.positionIndex, selfTop)
            },
            goTo(e){
                console.log(e)
                const id = e.currentTarget.dataset.id
                wepy.navigateTo({
                    url: `goodsInfo?id=${id}`
                })
            }
        }
        getScrollTopIndex(selfTop){
            let currentIndex = 0
            for(let i = 0, I = this.titleTop.length; i < I; i++){
                if(i == I-1){
                    if(selfTop => this.titleTop[i]){
                        currentIndex = i
                    }
                }else {
                    if(selfTop >= this.titleTop[i] && selfTop < this.titleTop[i + 1]){
                        currentIndex = i
                        break
                    }
                }
            }
            return currentIndex
        }
        onLoad(){
            
        }
    }
</script>


3. page页面  来了 

<style lang="scss">
    page{
        background: #f4f6f8;
    }
    .category_deails{
        height: 100%;
        display: flex;
        &_nav{
            width: 180rpx;
            height: 100%;
            flex-shrink: 0;
            border-left: 1px solid #eee;
        }
        &_view{
            flex: 1;
            flex-shrink: 1;
            height: 100%;
            margin-left: 21rpx;
        }
    }

</style>

<template>
    <view class="category_deails">
        <view class="category_deails_nav">
            <left-nav :navDeails.sync="navDeails" :selectedId.sync="selectedId" :navScrollTop.sync="navScrollTop" @change.user="navChange"></left-nav>
        </view>
        <view class="category_deails_view">
            <view-scroll :viewDeails.sync="viewDeails" :scrollTop.sync="scrollTop" :titleTop.sync="titleTop" @change.user="viewChange"></view-scroll>
        </view>

    </view>
</template>

<script>

    import wepy from 'wepy'
    import leftNav from '../components/ScrollNav'
    import ScrollView from '../components/ScrollView'
//    import retainedDecimalMoney from '../mixins/retainedDecimalMoney'
//    import getExtJson from '../mixins/getExtJson'

    export default class categoryScrollDetail extends wepy.page {
        components = {
            'left-nav': leftNav,
            'view-scroll': ScrollView
        }
        data = {
            api_host: 'https://www.xiaoniren.cn',
            config_id: '634',
            navDeails: [
                {
                    idName: 'apply'
                }
            ],
            viewDeails: {
                // apple: {
                //     name: '',
                //     children: [

                //     ]
                // }
            },
            selectedId: 1,
            titleTop: [],
            scrollTop: 0,
            navId: [],
            navTop: [],
            navScrollTop: 0
        }
        getCategoryData(){
            return new Promise( (resolve, reject) => {
                wepy.request({
                    url: `${this.api_host}/restapi/goods-category`,
                    data: {
                        config_id: this.config_id,
                        type: 0
                    },
                    success: res => {
                        if(res.data.success){
                            this.navDeails = res.data.data.items.filter( item => {
                                return item.level == 1
                            })
                            this.$apply()
                            resolve(this.navDeails)
                        }

                    }
                })
            })

        }
        getGoodsData(){
            wepy.request({
                url: `${this.api_host}/restapi/goods`,
                data: {
                    config_id: this.config_id
                },
                success: res => {
                    this.navId = []
                    this.navDeails.forEach( element => {
                        this.viewDeails['s' + element.id] = {}
                        this.viewDeails['s' + element.id].name = element.name
                        this.navId.push(element.id)
                        this.viewDeails['s' + element.id].children = res.data.data.items.filter( item => {
                            if(item.category_id == element.id){
                                if(item.thumb.indexOf('http') == -1){
                                    item.thumb = `${this.api_host}${item.thumb}`
                                }
//                                item.price = retainedDecimalMoney(item.price)
                                return item
                            }

                        })
                    })
                    this.$apply()
                    setTimeout(() => {
                        wx.createSelectorQuery()
                            .selectAll('.scroll_view_items_tit')
                            .boundingClientRect()
                            .exec( res => {
                                this.titleTop = res[0].map( item => {
                                    return item.top
                                })
                                this.$apply()
                                this.navId.forEach( (item, index) => {
                                    if(item == this.selectedId){
                                        this.scrollTop = this.titleTop[index]
                                    }
                                })
                            })
                        wx.createSelectorQuery()
                            .selectAll('.scroll_nav_items')
                            .boundingClientRect()
                            .exec( res => {
                                this.navTop = res[0].map( item => {
                                    return item.top
                                })
                                this.$apply()
                                this.navId.forEach( (item, index) => {
                                    if(item == this.selectedId){
                                        wx.createSelectorQuery()
                                            .select('.category_deails_nav')
                                            .fields({
                                                size: true
                                            }).exec( res => {
                                                if(res[0].height / 2 < this.navTop[index]){
                                                    this.navScrollTop = (43 * index - res[0].height / 2) + 120
                                                }else{
                                                    this.navScrollTop = 0
                                                }
                                            })
                                    }
                                })
                            })
                    }, 300)
                }
            })
        }
        methods = {
            navChange(index, id){
                if(this.scrollTop == this.titleTop[index]){
                    this.scrollTop = 0.01
                    return
                }
                this.scrollTop = this.titleTop[index]
            },
            viewChange(index, currentScrollTop){
                this.selectedId = this.navId[index]
                wx.createSelectorQuery()
                    .select('.category_deails_nav')
                    .fields({
                        size: true
                    }).exec( res => {
                        if(res[0].height / 2 < this.navTop[index]){
                            this.navScrollTop = (43 * index - res[0].height / 2) + 120
                        }else{
                            this.navScrollTop = 0
                        }
                    })
            }
        }
        onLoad(option){
//            getExtJson.call(this)
            // wepy.showLoading({
            //     title: '加载中...',
            //     mask: true
            // })
//            wepy.setNavigationBarTitle({
//                title: option.name
//            })
            this.getCategoryData().then( res => {
                this.getGoodsData()
            })

            this.selectedId = +option.id
            this.$apply()
        }
    }
</script>



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值