vue 点击滚动时间轴

复制代码
<template>
  <div class="background">
    <div class="sjz">
      <div class="iconDiv">
        <a-icon
          :class="showMonth[0].yearsMonth == startTime ? 'disabledIcon' : 'sjzIcon'"
          type="up-circle"
          @click="upSjz"
          theme="filled"
        />
      </div>
      <!-- 中间月份 -->
      <div class="monthList">
        <div v-for="(item, index) in showMonth" :key="index" class="monthItem">
          <span v-if="item.yearsMonth.indexOf('01') != -1">
            <!-- 年份显示 -->
            <div class="yearClass">
              <div>{{ item.yearsMonth.substring(0, 4) }}年</div>
              <img src="~@/assets/yeardown.png" alt="" class="yeardown" />
            </div>
            <!-- 判断是否可以点击 -->
            <span v-if="!item.clickMark">
              <div class="disabledCorsor">
                <span>
                  {{
                    item.yearsMonth.substring(5, 6) == 0
                      ? item.yearsMonth.substring(6, 7) + '月'
                      : item.yearsMonth.substring(5, 7) + '月'
                  }}
                </span>
              </div>
            </span>
            <span v-else>
              <div
                :class="item.yearsMonth == selectMonth ? 'selectMonth' : 'monthText'"
                @click="selectClick(item.yearsMonth)"
              >
                <span v-if="item.yearsMonth == selectMonth">
                  {{ item.yearsMonth }}
                </span>
                <span v-else>
                  {{
                    item.yearsMonth.substring(5, 6) == 0
                      ? item.yearsMonth.substring(6, 7) + '月'
                      : item.yearsMonth.substring(5, 7) + '月'
                  }}
                </span>
              </div>
            </span>
          </span>
          <span v-else>
            <!-- 判断是否可以点击 -->
            <span v-if="!item.clickMark">
              <div class="disabledCorsor">
                <span>
                  {{
                    item.yearsMonth.substring(5, 6) == 0
                      ? item.yearsMonth.substring(6, 7) + '月'
                      : item.yearsMonth.substring(5, 7) + '月'
                  }}
                </span>
              </div>
            </span>
            <span v-else>
              <div
                :class="item.yearsMonth == selectMonth ? 'selectMonth' : 'monthText'"
                @click="selectClick(item.yearsMonth)"
              >
                <span v-if="item.yearsMonth == selectMonth">
                  {{ item.yearsMonth }}
                </span>
                <span v-else>
                  {{
                    item.yearsMonth.substring(5, 6) == 0
                      ? item.yearsMonth.substring(6, 7) + '月'
                      : item.yearsMonth.substring(5, 7) + '月'
                  }}
                </span>
              </div>
            </span>
          </span>
        </div>
      </div>
      <div class="iconDiv">
        <a-icon
          :class="showMonth[showMonth.length - 1].yearsMonth == lastMonth ? 'disabledIcon' : 'sjzIcon'"
          class="sjzIcon"
          type="down-circle"
          @click="downSjz"
          theme="filled"
        />
      </div>
    </div>
  </div>
</template>

<script>
import moment from 'moment'

export default {
  data() {
    return {
      // 时间轴
      monthList: [],
      showMonth: [],
      minMonthNum: 0,
      maxMonthNum: 0,
      selectMonth: '',
      // 最终日期
      lastMonth: '',
      startTime:'',
      endTime:'',
    }
  },
  created() {
    var that = this
    that.startTime = '2020-10'
    that.endTime = '2024-12'
    // 时间轴
    that.monthList = that.timeline([that.startTime, that.endTime])  //传入两个时间端,计算出所有的月份
    if (that.monthList.length >= 12) {
      that.minMonthNum = that.monthList.length - 12
      that.maxMonthNum = that.monthList.length
    } else {
      that.minMonthNum = 0
      that.maxMonthNum = that.monthList.length
    }
    that.showMonth = that.monthList.slice(that.minMonthNum, that.maxMonthNum)
    that.selectMonth = that.endTime
    that.lastMonth = that.monthList[that.monthList.length - 1].yearsMonth
  },
  methods: {
    moment,
    // 时间轴
    timeline(date) {
      const startDate = new Date(date[0])
      const endDate = new Date(date[1])
      const result = []
      while (startDate <= endDate) {
        result.push({ yearsMonth: moment(startDate).format('YYYY-MM'), clickMark: true })
        startDate.setMonth(startDate.getMonth() + 1)
      }
      return result
    },
    // 向上
    upSjz() {
      if (this.showMonth[0].yearsMonth != this.startTime) {
        this.minMonthNum = this.minMonthNum - 1
        this.maxMonthNum = this.maxMonthNum - 1
        this.showMonth = this.monthList.slice(this.minMonthNum, this.maxMonthNum)
      }
    },
    // 向下
    downSjz() {
      if (this.showMonth[this.showMonth.length - 1].yearsMonth != this.lastMonth) {
        this.minMonthNum = this.minMonthNum + 1
        this.maxMonthNum = this.maxMonthNum + 1
        this.showMonth = this.monthList.slice(this.minMonthNum, this.maxMonthNum)
      }
    },
    // 选择月份
    selectClick(item) {
      this.selectMonth = item
    },
  },
}
</script>

<style lang="less" scoped>
.sjz {
  width: 72px;
  border: 1px solid #e8e8e8;
  margin-left: 10px;
}

.iconDiv {
  text-align: center;
}

.sjzIcon {
  font-size: 16px;
  font-style: normal;
  // cursor: pointer;
  color: #1677ff;
  margin: 8px 0;
}

.disabledIcon {
  font-size: 16px;
  font-style: normal;
  // cursor: pointer;
  color: #cccccc;
  margin: 8px 0;
}

.yearClass {
  font-size: 13px;
  // font-weight: 700;
  display: inline-block;
  text-align: center;
  width: 100%;
  color: #1677ff;
  font-weight: bold;
  position: relative;
}

.monthText {
  cursor: pointer;
  color: #333;
}

.monthList {
  text-align: center;
  // color: #333;
  // font-weight: 700;
  line-height: 26px;
  font-size: 12px;
}

.selectMonth {
  background: #1677ff;
  color: #fff;
  cursor: pointer;
  // border-radius: 18px;
  display: block;
  margin: auto;
  // width: 92%;
  line-height: 26px;
}

.yeardown {
  position: absolute;
  right: 31px;
  top: 20px;
  width: 8px;
}

.disabledCorsor {
  color: #e5e5e5;
  cursor: not-allowed;
}
</style>

展示的样式

注意:引入 moment 插件

相关推荐
阿虎儿13 分钟前
React Context 详解:从入门到性能优化
前端·vue.js·react.js
颜酱37 分钟前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
Sailing37 分钟前
🚀 别再乱写 16px 了!CSS 单位体系已经进入“计算时代”,真正的响应式布局
前端·css·面试
FansUnion1 小时前
我如何用 Next.js + Supabase + Cloudflare R2 搭建壁纸销售平台——月成本接近 $0
javascript
喝水的长颈鹿1 小时前
【大白话前端 03】Web 标准与最佳实践
前端
爱泡脚的鸡腿1 小时前
Node.js 拓展
前端·后端
左夕2 小时前
分不清apply,bind,call?看这篇文章就够了
前端·javascript
Zha0Zhun3 小时前
一个使用ViewBinding封装的Dialog
前端
兆子龙3 小时前
从微信小程序 data-id 到 React 列表性能优化:少用闭包,多用 data-*
前端
滕青山3 小时前
文本行过滤/筛选 在线工具核心JS实现
前端·javascript·vue.js