精细结构

目录

仿微博相册的一个功能

前言

最开始我是仿 vue-seamless-scroll 的 switch控制切换 功能写的一个功能。
vue-seamless-scroll 的 switch控制切换 怎么说呢,一眼难尽……
光看官网的 demo 我根本不知道怎么配置出 switch控制切换 的效果。

简单来说,左右两个箭头似乎、好像、应该、或许、大约、可能是要自己加?
反正我看了半天文档,也不知道要怎么把这两个箭头给设置出来。

而且官网上的 demo 复制出来,也没有达到官网所展示的效果,那真的
哎……

说真的,我要的效果就是点击两侧的箭头可以切换显示的模块内容,
结果你和我说两个箭头以及点击效果要自己做?

自己做?
自己做?
自己做?

真的非常无语……

如果说 CSDN 的内容是 依托答辩,那 vue-seamless-scroll 官网的内容也是多呈不让。

所以,基于此,决定自己造一个轮子来玩一下。

实现方案

按下一步的时候,向右前进一格,[ ○ □ □ ] □ □ □ => [ □ ○ □ ] □ □ □
如果已经到最右,则把看不见的向左推一格 [ □ □ ○ ] □ □ □ => □ [ □ □ ○ ] □ □
如果已经到最后,则什么都不做 □ □ □ [ □ □ ○ ]

按上一步的时候,向左前进一格, □ □ □ [ □ ○ □ ] <= □ □ □ [ □ □ ○ ]
如果已经到最左,则把看不见的向右推一格 □ □ [ ○ □ □ ] □ <= □ □ □ [ ○ □ □ ]
如果已经到最前,则什么都不做 [ ○ □ □ ] □ □ □

功能名称

写完后,发现这个功能和 vue-seamless-scroll 的 switch控制切换 似乎不太像,
然后再想了想,叫走马灯?似乎也不像
稍微有些纠结于这个功能到底该叫什么
最后在刷微博的时候,一拍脑袋想到,这不就是微博的相册么~

于是这个功能的名字也就有了
其他的就看代码吧~

代码

<template>
  <div>
    <div>选中:</div>
    <div class="seamless-scroll-detail-big-box">
      <!--
        循环的时候,把所有主控全部循环到
        但只展示 [first, first + 3) 之间的内容
      -->
      <div class="seamless-scroll-detail-btn-box">
        <div :class="'btn-box ' + (leftDisabled ? 'disaebld-btn-box' : 'active-btn-box')" @click="onPrev">《&nbsp;&nbsp;</div>
      </div>
      <div class="seamless-scroll-detail-data-box" v-loading="loading">
        <div v-if="items.length > 0">
          <div v-for="(item, index) in items" :key="index"  v-if="index >= first && index < first + 3">
            <div :class="now.index === (index) ? 'is-active' : 'not-active'" @click="onChangeShow(index)">
              
            </div>
          </div>
        </div>
        <div v-else>
          <div class="empty-data-box">
            <el-empty description="暂无数据" />
          </div>
        </div>
      </div>
      <div class="seamless-scroll-detail-btn-box">
        <div :class="'btn-box ' + (rightDisabled ? 'disaebld-btn-box' : 'active-btn-box')" @click="onNext">&nbsp;&nbsp;》</div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      loading: false,
      leftDisabled: true,
      rightDisabled: false,
      items: [ { value: 1 }, { value: 2 }, { value: 3 }, { value: 4 }, { value: 5 }, { value: 6 } ],
      first: 0,
      position: 0,
      now: { // 当前活跃对象
        index: 0,
        value: {}
      },
    }
  },
  created () {
    this.now.value = this.items[0];
  },
  methods: {
    /*
      按下一步的时候,向右前进一格,[ ○ □ □ ] □ □ □ => [ □ ○ □ ] □ □ □
      如果已经到最右,则把看不见的向左推一格 [ □ □ ○ ] □ □ □  => □ [ □ □ ○ ] □ □
      如果已经到最后,则什么都不做 □ □ □ [ □ □ ○ ]

      按上一步的时候,向左前进一格,  □ □ □ [ □ ○ □ ] <= □ □ □ [ □ □ ○ ]
      如果已经到最左,则把看不见的向右推一格 □ □ [ ○ □ □ ] □ <= □ □ □ [ ○ □ □ ] 
      如果已经到最前,则什么都不做 [ ○ □ □ ] □ □ □

      初始值(first)= 0
      显示范围:[first, first + 3)
      现在位置( position ) = 0
      */
      onChangeIndex () {
      // this.nowIndex = index;
      this.selectedSingleVal = "voltage";
      this.now.value = this.items[this.now.index];
    },
    onChangeShow (index) {
      this.now.index = index;
      this.position = index - this.first;
      if (this.first >= 0) {
        this.leftDisabled = false;
      } else {
        this.leftDisabled = true;
      }
      if (this.first < this.items.length - 1) {
        this.rightDisabled = false;
      } else {
        this.rightDisabled = true;
      }
      this.onChangeIndex();
    },
    onNext () {

      if (this.rightDisabled) return;

      /*
        点击下一步:
        now.index++
        position++
        如果 position > 2 (超出显示)
        first ++
        position = 2
        否则 first = 0
        */
      this.leftDisabled = false;
      if (this.items.length === 0)  return;
      this.now.index++;
      if (this.now.index === this.items.length - 1) {
          this.rightDisabled = true;
      }
      if (this.now.index === this.items.length) {
        this.now.index =  this.items.length - 1;
        this.rightDisabled = true;
        alert('后面没有了');
        return;
      }
      this.position++;
      if (this.position > 2) {
        this.position = 2;
        this.first++;
        if (this.first > this.items.length - 3) {
          this.first = this.items.length - 3;
          this.rightDisabled = true;
          alert('后面没有了');
        }
      }

      this.onChangeIndex();
    },
    onPrev () {

      if (this.leftDisabled) return;

      /*
        点击上一步
        now.index--
        poition--
        如果 position < 0 (超出显示)
        position = 0
        first --
        如果 fisrt < 0 => first - 0
        否则
        first = 0
        */
      this.rightDisabled = false;
      if (this.items.length === 0)  return;
      this.now.index--;
      if (this.now.index === 0) {
          this.leftDisabled = true;
      }
      if (this.now.index < 0) {
        this.now.index = 0;
        this.leftDisabled = true;
        alert('前面没有了');
        return;
      }
      this.position--;
      if (this.position < 0) {
         // □ □ □ [ ○ □ □ ]
        this.position = 0;

        // 向左移动的时候,一般情况下只要 first-- 即可,直到 first 为 0
        this.first--;
        if (this.first < 0) {
          this.first = 0;
          this.leftDisabled = true;
          alert('前面没有了');
        }
      }

      this.onChangeIndex();
    },
  }
}
</script>
<style lang="scss" scoped>
.seamless-scroll-detail-big-box {
  >div {
    display: inline-block;
    vertical-align: middle;
    height: 450px;
  }

  .seamless-scroll-detail-btn-box {
    width: 40px;
    text-align: center;

    .btn-box {
      margin-top: calc((78vh - 170px) / 2);
      display: block;
      height: 40px;
      line-height: 40px;

      background: rgba($color: #CCCCCC, $alpha: 0.5);
      border-radius: 50%;
    }

    .active-btn-box {
      cursor: pointer;
    }
    .active-btn-box:hover {
      background: rgba($color: #CCCCCC, $alpha: 0.3);
    }
    .active-btn-box:active {
      background: rgba($color: #fdff98, $alpha: 0.5);
    }
    .disaebld-btn-box {
      cursor: not-allowed;
    }
  }

  .seamless-scroll-detail-data-box {
    width: calc(100% - 80px);
    >div {
      height: 100%;
      >div {
        width: 33.33%;
        height: 100%;
        display: inline-block;
        margin-top: 40px;
        vertical-align: top;
        >div {
          margin: 0px 10px;
          height: calc(100% - 50px);
          cursor: pointer;
          >div {
            height: 100%;
          }
        }
      }

      .empty-data-box {
        >div {
          cursor: default !important;
        }
        width: 100% !important;
      }
    }
  }

  .is-active {
    background: rgba($color: #17579e, $alpha: 0.4);
  }

  .hidden-master-box {
    display: none;
  }
}
</style>

效果演示

http://codes.waygc.net/vue-wheel/#/album