美文网首页
Vue 实现左右联动(超详细!!!!)

Vue 实现左右联动(超详细!!!!)

作者: Kernel521 | 来源:发表于2021-04-22 08:56 被阅读0次

    这篇文章的中心思想呢,就是通过一个变量(flagShow)来控制两个盒子的显示与隐藏(一个是“红框”,另一个是“绿框”),下面我会把重要的部分写在代码的注释上,大家要细心看哦,我们先看一下整体的效果图:

    具体效果展示可以看这里https://player.bilibili.com/player.html?aid=460249298

    第一步:先来理顺一下结构,为什么要把它放在最上面呢?因为这个功能与结构的布局还是挺关键的

    <div class="classify-wrapper">
      <div class="left"></div> // 左边那一栏
      <div class="right" ref="scroll" @scroll="handleScroll"> // 右边那一栏滚动区域
        <div class="top-fixed-title fixed-title" v-show="!flagShow"></div> // 主要!!!标题fixed吸顶(红色区域)
        <div class="main-content" v-for="(item, index) in listData" :key="index"> // 右边的每一个模块
          <div class="top-title" ref="rightTit">{{item.name}}</div> // 正常的标题(蓝色区域)
          <div class="bottom-content"></div> // 内容部分(就是上面图片下面标题的部分)
          <div class="fixed-title" v-show="flagShow && index == currentIndex - 1"></div> //  主要!!!原来的吸顶部分现在随着文档流向上滚动(绿色区域)
        </div>
      </div>
    </div>
    

    第二步:参照上面的结构来看看具体的实现逻辑

    1. 定义的变量
    data() {
        listData: [],       // 接口获取到的总数据
        listHeight: [],     // 存放右边模块内容的高度
        scrollY: 0,         // 右边滚动时的scrollTop
        rightTitHeight: 0,  // 右边模块标题的高度
        currentIndex: 0,    // 用于判断左边的高亮以及右边标题的内容显示
        flagShow: false,    // 控制吸顶的标题 和 不吸顶的标题(显示与隐藏)
    }
    
    2. 先把右边每一模块的高度放到一个数组中
    getBoxHeight() {
       let rightTitHeight = this.rightTitHeight = this.$refs.rightTit.length ? this.$refs.rightTit[0].offsetHeight: 0;
       let rightItems = this.$refs.scroll.getElementsByClassName("main-content"); //获取指定类名的所有元素
       let height = 0;
       this.listHeight.push(height);
       for (let i = 0; i < rightItems.length; i++) {
         let item = rightItems[i]; // 右边的每一个模块(蓝色标题 + 标题下面所带的内容)
         height += item.clientHeight;
         this.listHeight.push(height - rightTitHeight); // 把右边模块内容的高度全都放到一个数组中
       }
       this.listData.forEach((item, index) => {
         // 把上面弄的那些高度分别放入总数据中,方便点击左边让右边滚动到所对应的模块
         this.$set(item, "distance", this.listHeight[index]); 
       });
     }
    
    3. 滚动的时候判断是否显示影藏那两个标题(红框与绿框)
    1. this.scrollY >= start:当滚动的scrollTop到达顶部吸顶红框与蓝框的交界处(也就是大于右边模块内容的高度)
    2. this.scrollY < end:当滚动的scrollTop小于(右边模块内容的高度 加上 右边模块标题的高度)
    handleScroll() {
       this.scrollY = this.$refs.scroll.scrollTop; // 先获取滚动元素的scrollTop,主要用它来进行判断
       for (let i = 0; i < this.listHeight.length; i++) {
         let start = this.listHeight[i + 1]; // 右边模块内容的高度
         let end = this.listHeight[i + 1] + this.rightTitHeight; // 右边模块内容的高度 加上 右边模块标题的高度
         
         if (this.scrollY >= start && this.scrollY < end) {
           this.flagShow = true; // 当满足条件时,红色区域隐藏,绿色区域显示
           this.currentIndex = i + 1;
           return;
         }
         this.flagShow = false; // 默认红色区域定位在顶部
       }
     },
    
    4. 点击左边标题联动右边

    通过scrollTop来让右边区域随着左边的点击而联动

    changeModel(index) {
        this.$refs.scroll.scrollTop = this.listData[index].distance + this.rightTitHeight;
        this.currentIndex = index;
    }
    

    第三步:结合上面所说,来看一下样式部分

    .classify-wrapper {
      width: 100%;
      height: 100vh;
      background: #f7f7f7;
      .left {
        width: 111px;
        height: 100%;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
      }
      .right {
        position: relative;
        flex: 1;
        width: 100%;
        height: 100%;
        background: #fff;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        .top-fixed-title { // !!!重要  红色区域
          position: fixed !important;
          top: 0 !important;
          z-index: 999 !important;
          background: #f00 !important;
        }
        .fixed-title { // !!!重要 绿色区域
          position: absolute;
          bottom: 0;
          z-index: 999;
          width: 249px;
          height: 45px;
          background: #0f0;
        }
        .main-content {
          position: relative;
          width: 100%;
          height: 100%;
          .top-title {
            height: 45px;
            background: #00f; // !!! 重要 蓝色区域
          }
        }
      }
    }
    

    以上就是这节的全部内容,欢迎各位大佬在下方评论区提问,如有不足,还望多多指教

    相关文章

      网友评论

          本文标题:Vue 实现左右联动(超详细!!!!)

          本文链接:https://www.haomeiwen.com/subject/wokxrltx.html