vue实现移动端左右菜单双向联动效果
作者:互联网
话不多说,上demo
<template> <div id="app"> <header>左右列表双向联动</header> <div class="content"> <!-- 左侧列表 --> <ul class="left_title" ref="left"> <li class="title_item" v-for="(item, index) in cateData" :key="index" :class="currentIndex === index ? 'active' : ''" @click="change(index)" > {{ item.name }} </li> </ul> <!-- 右侧内容区域 --> <div class="right_content"> <div class="container" ref="container"> <div ref="foodsUI" class="foodsUI"> <div class="list"> <div class="name">健康蔬菜</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> <div class="list"> <div class="name">时令蔬菜</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> <div class="list"> <div class="name">拨草</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> <div class="list"> <div class="name">1</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> <div class="list"> <div class="name">2</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> <div class="list"> <div class="name">3</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> <div class="list"> <div class="name">4</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> <div class="list"> <div class="name">5</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> <div class="list"> <div class="name">6</div> <ul> <li>苹果</li> <li>西红柿</li> <li>番茄</li> </ul> </div> </div> </div> </div> </div> </div> </template> <script> import BScroll from 'better-scroll' export default { data() { return { scroll: '', // 右侧滑动的y轴坐标(滑动过程中的实时变化) scrollY: 0, foodsScroll: '', // 所有右侧分类li的top组成的数组 tops: [], cateData: [ { name: '健康蔬菜' }, { name: '时令蔬菜' }, { name: '拨草' }, { name: '1' }, { name: '2' }, { name: '3' }, { name: '4' }, { name: '5' }, { name: '6' } ] } }, methods: { // 初始化滚动 initScroll() { const container = this.$refs.container this.scroll = new BScroll(container) /* eslint-disable no-new */ new BScroll('.left_title', { click: true }) // 监听右侧列表 this.foodsScroll = new BScroll('.container', { // 惯性滑动不会被触发 probeType: 2, click: true }) // 给右侧列表绑定scroll监听 this.foodsScroll.on('scroll', ({ x, y }) => { // math.abs绝对值 this.scrollY = Math.abs(y) console.log(x, y) }) // 给右侧列表绑定滚动结束监听,滚动结束后改变左侧列表背景颜色 this.foodsScroll.on('scrollEnd', ({ x, y }) => { this.scrollY = Math.abs(y) }) }, // 初始化tops _initTops() { // 1.初始化tops const tops = [] let top = 0 tops.push(top) // 2.搜集 // 找到所有分类的li const lis = this.$refs.foodsUI.getElementsByClassName('list') Array.prototype.slice.call(lis).forEach(li => { top += li.clientHeight tops.push(top) }) // 3。更新数据 this.tops = tops console.log(this.tops) }, // 点击左侧列表右侧滚动到相应位置 change(index) { // 得到目标scrollY const y = this.tops[index] // 立即更新scrollY this.scrollY = y // 平滑滑动右侧列表 this.foodsScroll.scrollTo(0, -y, 300) } }, computed: { // 计算当前分类的下表 currentIndex() { // 得到条件数据 const { scrollY, tops } = this // 根据条件计算产出一个结果 const index = tops.findIndex((top, index) => { return scrollY >= top && scrollY < tops[index + 1] }) // 返会结果 return index } }, mounted() { this.$nextTick(() => { this.initScroll() this._initTops() }) } } </script> <style scoped> header { height: 50px; width: 100%; background-color: green; color: #fff; font-size: 18px; display: flex; justify-content: center; align-items: center; } .content { display: flex; } .left_title { flex: 1; margin-right: 5px; } .title_item { height: 35px; width: 100%; border: 1px solid #ccc; display: flex; justify-content: center; align-items: center; font-size: 18px; border-bottom: none; } .title_item :last-child { border-bottom: 1px solid #ccc; } .right_content { flex: 3; position: relative; } .name { text-align: center; padding: 20px; font-size: 28px; } .list li{ font-size: 20px; } .container { overflow: hidden; height: calc(100vh - 50px); } .active { background-color: red; color: #fff; } .list { height: 200px; border: 1px solid #ccc; } .foodsUI { padding-bottom: 400px; } </style>
标签:西红柿,vue,name,top,tops,scrollY,菜单,双向,番茄 来源: https://www.cnblogs.com/anna001/p/16034335.html