其他分享
首页 > 其他分享> > vue实现移动端左右菜单双向联动效果

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