vue中实现外卖侧边栏左右联动

该文介绍了如何使用better-scroll库在Vue.js应用中实现在右侧商品列表滚动时,左侧分类标题自动改变。主要步骤包括安装库,初始化滚动,监听滚动事件,计算当前分类的下标,以及处理点击事件来定位滚动位置。
摘要由CSDN通过智能技术生成

 在外卖app中,经常能看到右侧商品列表滚动变化,左边的分类标题也跟着改变。实现的思路如下:

1、先安装better-scroll库:

npm install --save better-scroll

2、在组件中引入

import BScroll from "@better-scroll/core";
import MouseWheel from "@better-scroll/mouse-wheel";
BScroll.use(MouseWheel);

3、在data中定义scroll、scrollGoods分别代表左侧滚动和右侧滚动,并定义好scrollY(用来收集y的坐标)和tops(存放元素高度的数组)。

data() {
    return {
        scrollY: 0,
        tops: [],
        scroll: '',
        scrollGoods: ''
    };
},

4、先定义初始化滚动和高度的方法。

4.1、在初始化滚动的时候,需要配置click为true,因为better-scroll默认阻止了原生的点击事件。

4.2、在BScroll对象上通过on监听事件回调:scroll是滚动监听、scrollEnd是滚动结束的监听。

4.3、在初始化高度的时候,用querySelectorAll获取到的是一个伪数组,可以通过Array.prototype.slice.call(lis)或者Array.from(lis)转化为一个真数组。再对数组中的每一个元素进行遍历,push到tops中。

初始化后的tops为[0, 80, 160, 240, 320, 400, 480, 560, 640, 720, 800]

methods: {
    // 初始化滚动
    _initScroll() {
        this.scroll = new BScroll(this.$refs.scroll, {
            mouseWheel: true,
            scrollY: true,
            click: true
        });
        this.scrollGoods = new BScroll(this.$refs.scrollGoods, {
            mouseWheel: true,
            scrollY: true,
            click: true,
            probeType: 3, // 滚动的方式(0、1、2、3)3是受惯性滚动
        });
        // 滚动监听
        this.scrollGoods.on("scroll", (position) => {
            // position对象上有两个值:x、y
            // console.log(position.x, position.y);
            // 对监听到进行处理
            this.scrollY = Math.abs(Math.round(position.y));
        });
        // 滚动结束的监听
        this.scrollGoods.on("scrollEnd", (position) => {
            this.scrollY = Math.abs(Math.round(position.y));
        });
    },
    // 初始化高度
    _initTops() {
        let tops = [];
        let top = 0; // 类似于求和累加
        tops.push(top);
        // 收集tops
        let lis = document.querySelectorAll(".goods-content"); // 伪数组
        Array.prototype.slice.call(lis).forEach((li) => {
            top += li.clientHeight;
            tops.push(top);
        });
        // 更新tops
        this.tops = tops;
    },
}

5、接下来就是要考虑什么时候初始化滚动和初始化高度。

(要初始化滚动和高度,初始化的时机很重要,必须要知道dom元素的高度,而dom元素的高度是通过请求来的数据渲染而成的,这时候则需要在watch搭配$nextTick进行初始化。)

这里的goodsList是请求来的列表数据

watch: {
    goodsList(val) {
        this.$nextTick(() => {
            this._initScroll();
            this._initTops();
        });
    }
}

6、计算得到当前分类的下标。

计算下标的时候需要注意的是:当前滚动距离scrollY是需要大于等于当前top值(top是tops数组中的每一项),还要小于下一个top,拿到在这个区间内的数的下标,返回index。

computed: {
    // 计算当前分类的下标
    currentIndex() {
        // 得到条件数据
        let { scrollY, tops } = this;
        // 根据条件计算产生一个结果
        // findIndex方法常用来查找数组中满足条件的第一项元素的下标
        // 返回的是满足条件的第一项元素的下标,这要注意的是findIndex会给数组中的每一项执行一个函数来判断是否满足表达式,如果满足条件后,剩下的元素则不再执行
        let index = tops.findIndex((top, index) => {
            // scrollY要大于等于当前top值,还要小于下一个top
            // tops数据:[0, 80, 160, 240, 320, 400, 480, 560, 640, 720, 800]
            return scrollY >= top && scrollY < tops[index + 1];
        });
        // 返回结果
        return index;
    },
},

让当前v-for循环元素的index下标和currentIndex比较,如果相等,则动态添加类名active。

<li
  v-for="(item, index) in sidebarList"
  :key="index"
  :class="index === currentIndex ? 'active' : ''"
>
</li>

7、实现点击左侧分类的li,右侧商品列表滚动定位到指定位置。

<li
  v-for="(item, index) in sidebarList"
  :key="index"
  :class="index === currentIndex ? 'active' : ''"
  @click="isActive(index)"
>
</li>

对li绑定点击事件,需要传入点击元素的下标。

通过js控制跳转(scrollTo方法)

isActive(index) {
    // 获取到需要跳转的高度
    const scrollY = this.tops[index];
    this.scrollY = scrollY;
    // scrollTo(x, y, 动画时间)
    this.scrollGoods.scrollTo(0, -scrollY, 300);
},

效果展示

屏幕录制2023-02-01 01.26.35

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值