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

这篇文章的中心思想呢,就是通过一个变量(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; // !!! 重要 蓝色区域
      }
    }
  }
}

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容