uniapp实现微信小程序商品分类侧边栏效果

前言:微信小程序的代码实现,uniapp与原生代码差异不大,语法格式可对比swiper实现的原生代码和scrollview实现的uniapp代码。

参考资料:

微信小程序api>>https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html

获取元素/组件与顶部的距离>>https://www.jianshu.com/p/fe72cff2b808

swiper实现的简易demo>>https://blog.csdn.net/weixin_41599291/article/details/93650074

功能实现:

右侧滚动,左侧会对应高亮显示;

左侧是否重复点击,右侧显示相应数据,置顶;

效果图:

    

代码:

<template>
    <view>
        <view style="text-align: center;">搜索栏</view>
        <view class='productNav'>
          <view class='left'>
            <view :class="posi == 'id'+index ?'selected':'normal'" @tap='switchNav("id"+index, index)' v-for="(item, index) in dataList" :key="index">{{item.name}}</view>
          </view>
          <view class='right'>
            <scroll-view scroll-y="true" class="scroll" @scroll="scroll" :scroll-into-view="posi" :scroll-top="scrollTop">
                <view :id="item.id" v-for="(item, index) in dataList" :key="index">
                    <view class="title">{{item.name}}</view>
                    <view v-for="(subitem, i) in item.num" :key="i">{{item.name}}{{subitem}}</view>
                </view>
            </scroll-view>
          </view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                posi: '',
                scrollTop: 0,
                data: ['为您推荐','电脑','手机','美妆'] ,//模拟数据
                dataList: [], //循环数据
                dataEleHeight: [] ,//获取data数组中各个元素的高度
                topList: [], //计算得到各个元素与顶部的距离
                scrollHeight: 500 //滚动区域的高度
            }
        },
        onLoad() {
            //初始化数据,相当于请求数据
            for (let i = 0; i < this.data.length; i++) {
                let rand = parseInt(Math.random()*100,10);
                let num = []
                for(let j = 0; j < rand; j++) {
                    num.push(j);
                }
                let obj = {
                    id: 'id'+i,
                    name: this.data[i],
                    num: num
                }
                if(i == 0){
                    this.posi = obj.id
                }
                this.dataList.push(obj)
            }
        },
        watch: {
            dataEleHeight(val) {
                if (val.length == this.dataList.length) {
                    //判断是第几个元素,高度设置为之前的元素高度之和
                    let top = 0
                    for (let i in this.dataEleHeight) {
                        if (i >= 0 && i < this.dataEleHeight.length) {
                            if(i != 0) {
                                top += this.dataEleHeight[i-1].height
                            }
                            this.topList.push(top);
                        }
                    }
                }
                console.log(this.topList)
            }
        },
        mounted(){
            let that = this
            for (let i = 0; i < this.dataList.length; i++) {
                //获取元素属性最好是在渲染之后执行,避免获取空值
                uni.createSelectorQuery().in(this).select('#'+this.dataList[i].id).boundingClientRect(function(rect){
                    let obj = {
                        id: that.dataList[i].id,
                        height: rect.height
                    }
                    that.dataEleHeight.push(obj);
                }).exec();
            }
        },
        methods: {
            scroll(e) {
                let index = this.posi.substring(2)
                //判断e.detail.scrollTop在哪个范围,就高亮显示哪个分类
                for(let i in this.topList){
                    if (i < this.topList.length - 1 && this.topList[i] <= e.detail.scrollTop && e.detail.scrollTop < this.topList[parseInt(i) + 1]) {
                        this.posi = this.dataList[i].id
                        break;
                    }
                    if (i == this.topList.length - 1) {
                        this.posi = this.dataList[i].id
                    }
                }
                this.scrollTop = e.detail.scrollTop //解决重复点击菜单时右侧数据不变的问题
            },
            switchNav: function (e, index) {
                if(this.posi != e){
                    this.posi = e
                } else {
                    //重复点击一样要定位到最开头的位置
                    this.scrollTop = this.topList[index];
                }
            }
        }
    }
</script>

<style>
    .productNav{
      display: flex;
      flex-direction: row;
      font-family: "Microsoft YaHei"
    }
    .left{
      width: 25%;
      font-size: 30rpx;
      background-color: #f4f4f4;
    }
    .left view{
      text-align: center;
      height: 90rpx;
      line-height: 90rpx;
    }
    .selected{
      background-color: #fff;
      border-left: 2px solid #E54847;
      font-weight: bold;
      color: #E54847;
    }
    .normal{
      background-color: #f4f4f4;
      border-bottom: 1px solid #f2f2f2;
    }
    .right{
      width:75%;
      margin: 0;
    }
    .scroll{
      height: 500px;
      text-align: center;
    }
    .title{
        background: #E54847;
        color: white;
    }
</style>

巨坑:for(let i in this.topList)中的  i  属于字符串,执行计算操作时必须先转数字int

猜你喜欢

转载自www.cnblogs.com/lightmusic/p/11890667.html