ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue实现移动端左右菜单双向联动效果

2022-03-21 14:06:13  阅读:222  来源: 互联网

标签:西红柿 vue name top tops scrollY 菜单 双向 番茄


 

 

 

 话不多说,上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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有