Vue 中使用better-scroll实现左右联动的效果

Vue 中使用better-scroll实现左右联动的效果

效果图
在这里插入图片描述

1. 说明
  1. 在使用better-scroll的时候需要先在全局注册一个实例化的对象this.leftScroll 和 this.rightScroll,方便在之后的代码中使用
  2. 在销毁页面的时候要清除掉实例化的对象,避免造成性能的溢出
    beforeDestroy() {
        this.left_Scroll.destroy()
        this.right_Scroll.destroy()
    }
    
  3. 使用的better-scroll的方法和属性
    3.1 click,用来开启点击事件
    3.2 probeType,用来获得滚动的位置
    3.3 scrollTo(x, y, time, easing)方法,滚动到指定的位置
    3.4 scrollToElement(el, time, offsetX, offsetY, easing),滚动到指定的目标元素
    3.5 scroll事件 滚动过程中,具体时机取决于选项中的 probeType
    3.6 事件的绑定通过on this.rightScroll.on('scroll',() => {})
  4. 实现左边滚动的方法主要是使用了scrollToElement(el, time, offsetX, offsetY, easing)
  5. 右边的联动效果需要考虑到最后一个元素的位置情况
2. 代码
  1. html代码
    <!-- 2.分类内容 -->
    <div class="classify_content">
        <!-- 左边的分类tab -->
        <div class="left_warp" ref="left_warp">
            <div class="left_warp_content" ref="left_warp_content">
                <div
                    :class="[index == isActive? 'isActive': '', 'left_item']"
                    v-for="(item,index) in 20"
                    :key="index"
                    @click="leftItemClick(index)"
                >数码{{index}}</div>
            </div>
        </div>
        <!-- 右边的内容 -->
        <div class="right_warp" ref="right_warp">
            <div class="right_warp_content" :style="right_warpPB" ref="right_warp_content">
                <div v-for="(item,index) in 20" :key="index" class="right_item">
                    <div class="title">数码{{index}}</div>
                    <div class="content">{{index}}</div>
                </div>
            </div>
        </div>
    </div>
    
  2. 初始化better-scroll
    import BScroll from 'better-scroll'
    export default{
    	mounted() {
            this.$nextTick(() => {
                this.init()
            })
        },
        data() {
            return {
                isActive: 0, // 当前的索引
                scrollY: 0, // 右边内容的滚动的高度
                rightItemArray: [], // 右边item的高度
                right_warpPaddingB: 0 // 设置右边内容的padding-bottom
            }
        },
        methods: {
        	// 初始化
            init() {
                this._init_left()
                this._init_right()
            },	
            // 初始化左边的 better-scroll
            _init_left() {
                let left_wrapper = this.$refs.left_warp
                // 初始化左边的 better-scroll
                this.left_Scroll = new BScroll(left_wrapper, {
                    click: true
                })
            },
            _init_right(){
            	let right_warp = this.$refs.right_warp
                // 初始化右边的 better-scroll
                this.right_Scroll = new BScroll(right_warp, {
                    click: true,
                    probeType: 3
                })
            }
        }
    }
    
  3. 左边点击效果,传递的index就是当前点击的那个元素,使用scrollToElement方法就可以跳转到指定的位置
    // 左边的点击事件
    leftItemClick(index) {
        if (this.isActive === index) return
        this.isActive = index
        this.left_warp_item(index)
        // 这个方法是在点击左边的时候,右边的内容联动
        this.right_Scroll.scrollTo(0,-this.rightItemArray[index],200)
    },
    // 点击的时候左边 滚动
    left_warp_item(index) {
        const getItemElement = this.$refs.left_warp_content.children[index]
        this.left_Scroll.scrollToElement(getItemElement, 300, 0, true, 'easing')
    }
    
  4. 右边的联动效果,
    4.1 在初始化的时候就需要获取到每个item所在位置的高度
    4.2 并且绑定scroll事件用来监听滚动到的位置
    4.3 然后在scroll事件中触发左边的滚动事件this.left_warp_item(getIndex)
    _init_right() {
        let right_warp = this.$refs.right_warp
        // 初始化右边的 better-scroll
        this.right_Scroll = new BScroll(right_warp, {
            click: true,
            probeType: 3
        })
        // 获取右边所有item的高度
        let listArray = []
        let top = 0
        listArray.push(0)
        // 获取右边所有的 right_item 数组
        const itemsEL = this.$refs.right_warp_content.children
        itemsEL.forEach(item => {
            top += item.offsetHeight
            listArray.push(top)
        })
        this.rightItemArray = listArray
        // 右边内容的滑动事件
        this.right_Scroll.on('scroll', pos => {
            this.scrollY = Math.abs(pos.y)
            let getIndex = this.rightItemArray.findIndex((item, index) => {
                return this.scrollY >= item && this.rightItemArray[index + 1] > this.scrollY
            })
            this.isActive = getIndex
            this.left_warp_item(getIndex)
        })
    }
    
  5. 这里在使用的时候考虑的是,如果最后一个的高度比屏幕的高度小的时候,需要给item的父容器设置padding-bottom来撑大item的父容器,因此,在初始化右边容器的时候,就需要看是否需要添加padding-bottom
    // 初始化右边的 better-scroll 并且绑定事件
    _init_right() {
        let right_warp = this.$refs.right_warp
        // 初始化右边的 better-scroll
        this.right_Scroll = new BScroll(right_warp, {
            click: true,
            probeType: 3
        })
        // 获取右边所有item的高度
        let listArray = []
        let top = 0
        listArray.push(0)
        // 获取右边所有的 right_item 数组
        const itemsEL = this.$refs.right_warp_content.children
        itemsEL.forEach(item => {
            top += item.offsetHeight
            listArray.push(top)
        })
        this.rightItemArray = listArray
        // 计算右边内容需要添加的 padding-bottom
        this.cala_right_warpPaddingB()
        // 右边内容的滑动事件
        this.right_Scroll.on('scroll', pos => {
            this.scrollY = Math.abs(pos.y)
            let getIndex = this.rightItemArray.findIndex((item, index) => {
                return this.scrollY >= item && this.rightItemArray[index + 1] > this.scrollY
            })
            this.isActive = getIndex
            this.left_warp_item(getIndex)
        })
    },
    // 计算右边内容需要添加的 padding-bottom
    cala_right_warpPaddingB() {
        // 获取 右边最外面盒子的高度
        const right_warpH = this.$refs.right_warp.clientHeight
        // 获取最后一个元素的高度
        const itemsELH = this.$refs.right_warp_content.lastElementChild.clientHeight
        // 说明最后一个盒子的高度没有屏幕高 需要设置 padding-bottom
        if(right_warpH > itemsELH) {
            this.right_warpPaddingB = right_warpH - itemsELH
        }
    }
    
  6. 动态设置style
    computed: {
        right_warpPB() {
            return `padding-bottom: ${this.right_warpPaddingB}px`
        }
    }
    
3. 完整JS代码
<script>
import BScroll from 'better-scroll'
export default {
    computed: {
        right_warpPB() {
            return `padding-bottom: ${this.right_warpPaddingB}px`
        }
    },
    data() {
        return {
            isActive: 0, // 当前的索引
            scrollY: 0, // 右边内容的滚动的高度
            rightItemArray: [], // 右边每个item的高度
            right_warpPaddingB: 0 // 设置右边内容的padding-bottom
        }
    },
    mounted() {
        this.$nextTick(() => {
            this.init()
        })
    },
    methods: {
        // 初始化
        init() {
            this._init_left()
            this._init_right()
        },
        // ------------------------------左边的 scroll 滚动 和 事件
        // 初始化左边的 better-scroll
        _init_left() {
            let left_wrapper = this.$refs.left_warp
            // 初始化左边的 better-scroll
            this.left_Scroll = new BScroll(left_wrapper, {
                click: true
            })
        },
        // 左边的点击事件
        leftItemClick(index) {
            if (this.isActive === index) return
            this.isActive = index
            this.left_warp_item(index)
            this.right_Scroll.scrollTo(0, -this.rightItemArray[index],200)
        },
        // 点击的时候左边 滚动
        left_warp_item(index) {
            const getItemElement = this.$refs.left_warp_content.children[index]
            this.left_Scroll.scrollToElement(getItemElement, 300, 0, true, 'easing')
        },
        // ------------------------------右边的 scroll 滚动 和 事件
        // 初始化右边的 better-scroll 并且绑定事件
        _init_right() {
            let right_warp = this.$refs.right_warp
            // 初始化右边的 better-scroll
            this.right_Scroll = new BScroll(right_warp, {
                click: true,
                probeType: 3
            })
            // 获取右边所有item的高度
            let listArray = []
            let top = 0
            listArray.push(0)
            // 获取右边所有的 right_item 数组
            const itemsEL = this.$refs.right_warp_content.children
            itemsEL.forEach(item => {
                top += item.offsetHeight
                listArray.push(top)
            })
            this.rightItemArray = listArray
            // 计算右边内容需要添加的 padding-bottom
            this.cala_right_warpPaddingB()
            // 右边内容的滑动事件
            this.right_Scroll.on('scroll', pos => {
                this.scrollY = Math.abs(pos.y)
                let getIndex = this.rightItemArray.findIndex((item, index) => {
                    return this.scrollY >= item && this.rightItemArray[index + 1] > this.scrollY
                })
                this.isActive = getIndex
                this.left_warp_item(getIndex)
            })
        },
        // 计算右边内容需要添加的 padding-bottom
        cala_right_warpPaddingB() {
            // 获取 右边最外面盒子的高度
            const right_warpH = this.$refs.right_warp.clientHeight
            // 获取最后一个元素的高度
            const itemsELH = this.$refs.right_warp_content.lastElementChild.clientHeight
            // 说明最后一个盒子的高度没有屏幕高 需要设置 padding-bottom
            if(right_warpH > itemsELH) {
                this.right_warpPaddingB = right_warpH - itemsELH
            }
        }
    },
    beforeDestroy() {
        this.left_Scroll.destroy()
        this.right_Scroll.destroy()
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Vue是一种用于构建用户界面的渐进式JavaScript框架,它可以帮助开发者更高效地构建单页面应用程序。而vue-better-scroll是基于Vue的一款优秀的滚动插件,它能够实现更流畅的滚动效果,并且支持上下左右的滚动和联动效果。 如果需要实现左右侧菜单的联动效果,我们可以通过使用vue-better-scrollscrollToElement方法来实现。首先,我们需要在Vue引入vue-better-scroll插件并进行配置。 在Vue实例的data,我们可以定义左右两个菜单的数据,例如leftMenu和rightMenu,并在created生命周期初始化数据。然后,在mounted生命周期,我们可以通过refs属性获取到两个菜单容器的DOM元素。 接下来,我们需要监听左边菜单的点击事件,当点击左边菜单的某个选项时,我们可以通过调用vue-better-scrollscrollToElement方法,将右边菜单滚动到对应的位置。通过传递目标元素的选择器或具体的DOM元素,我们可以实现左右菜单的联动效果。 具体实现时,我们可以在左边菜单的点击事件使用this.$refs来访问右边菜单容器,并调用scrollToElement方法,将目标元素滚动到可视区域。通过传递选择器或具体DOM元素作为参数,我们可以精确控制滚动的位置。 同时,为了视觉上更好的效果,我们还可以给目标元素添加样式,如高亮当前选项,以提升用户体验。 最后,通过一系列的事件处理和样式设置,我们就可以实现左右侧菜单的联动demo了。 以上就是使用Vuevue-better-scroll实现左右侧菜单联动demo的大致思路和步骤。通过合理运用这两个工具,我们可以轻松地实现出一个流畅、友好的用户界面效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值