【vue】卡片左右翻页组件

功能需求

请添加图片描述

  • 点击左右翻动按钮切换显示卡片
  • 底部圆点代表相应页码, 点击圆点显示指定页面卡片
  • 当切换到首页或最后一页时, 相应按钮为禁用状态

思路

  1. 需要保存总卡片数据 totalCardList , 总页码 pageNum, 当前展示的卡片 curCardList, 以及当前页码 curPage ;
  2. 初始化组件时, 用后台返回的数据更新 totalCardList 和 pageNum ;
  3. 翻页事件里, 做两件事: 更新当前页码 curPage 和 当前显示的卡片 curCardList, 其中, 更新 curCardList 的方法为
   this.curCardList = this.totalCardList.slice(
        (this.curPage - 1) * 4,
        this.curPage * 4
   )

注:

  1. 底部圆点可用 v-for=“index of pageNum” 来遍历显示, 注意index 由 1 开始计数;
  2. 卡片翻页也可用容器块的 scrolltoleft 方法, 但得根据卡片数量动态设置容器宽度, 且卡片宽度自适应得通过动态设置宽度来实现, 故弃用这种实现思路.

组件代码

<template>
  <div class="indicator-reports-cards">
    <div class="indicator-reports-cards-wrapper">
      <div class="indicator-reports-cards-wrapper-box">
        <div
          ref="card"
          class="indicator-reports-cards-content"
          v-for="(item, index) in curCardList"
          :key="index"
          @click="linkToReports(item.id)"
        >
          <div class="indicator-reports-cards-content-title">
            <div class="indicator-reports-cards-content-title-name">
              <title-tip :content="item.title" />
            </div>
            <div class="indicator-reports-cards-content-title-content">
              <img :src="require(`@/assets/clientHome/reportForm.png`)" />
            </div>
            <div
              class="indicator-reports-cards-content-title-bottom three-lines-ellipsis"
            >
              {{ item.detail }}
            </div>
          </div>
        </div>
      </div>
    </div>
    <button
      type="button"
      class="el-carousel__arrow el-carousel__arrow--left"
      @click="clickToLeft"
      :disabled="curPage == 1"
    >
      <i class="el-icon-arrow-left"></i>
    </button>
    <button
      type="button"
      class="el-carousel__arrow el-carousel__arrow--right"
      @click="clickToRight"
      :disabled="pageNum == curPage"
    >
      <i class="el-icon-arrow-right"></i>
    </button>
    <div class="dot-tag">
      <div
        class="dot"
        v-for="index of pageNum"
        :key="index"
        :class="curPage == index ? 'active' : ''"
        @click="handleClickDot(index)"
      ></div>
    </div>
  </div>
</template>
<script>
import * as api from '@/api/reports'

export default {
  name: 'IndicatorReportsCards',
  data() {
    return {
      totalCardList: [],
      curCardList: [],
      curPage: 1,
      pageNum: 1,
    }
  },
  mounted() {
    this.querytotalCardList()
  },
  methods: {
    querytotalCardList() {
      api.queryCardList().then((res) => {
        this.totalCardList = res.map((el) => ({
          title: el.domainName,
          id: el.id,
          detail: el.domainDesc,
          imgUrl: el.imgUrl,
        }))
        this.curCardList = this.totalCardList.slice(0, 4)
        this.pageNum = Math.ceil(this.totalCardList.length / 4)
      })
    },
    linkToReports(domainCardId) {
      this.$router.push({
        path: '/reports',
        query: { domainCardId },
      })
    },
    // 点击左箭头
    clickToLeft() {
      this.curPage--
      this.updateCardList()
    },
    // 点击右箭头
    clickToRight() {
      this.curPage++
      this.updateCardList()
    },
    // 点击圆点
    handleClickDot(index) {
      this.curPage = index
      this.updateCardList()
    },
    //更新卡片列表
    updateCardList() {
      this.curCardList = this.totalCardList.slice(
        (this.curPage - 1) * 4,
        this.curPage * 4
      )
    },
  },
}
</script>
<style lang="less" scoped>
.indicator-reports-cards {
  padding: 0 17.35% 0 18.5%;
  position: relative;

  &-wrapper {
    overflow-x: auto;

    &-box {
      display: flex;
      justify-content: center;
      // flex-wrap: wrap;
      justify-content: space-between;
    }

    &::-webkit-scrollbar {
      width: 0;
      height: 0;
    }
  }

  &-content {
    width: 25%;
    min-width: 25%;
    // width: 306px;
    // min-width: 306px;
    display: flex;
    align-items: center;
    // flex: 1 1 30%;
    // min-width: 0;
    padding: 0 10px 30px 10px;

    &:last-child {
      margin-right: auto;
    }
    &-title {
      box-shadow: 0px 0px 8px 2px rgba(223, 229, 238, 0.9);
      border-radius: 4px;
      padding: 20px;
      cursor: pointer;
      background-color: #ffffff;
      &-name {
        color: #333333;
        font-family: MicrosoftYaHei-Bold;
        font-size: 18px;
        font-weight: 700;
        // overflow: hidden;
        // text-overflow: ellipsis;
        // white-space: nowrap;
        padding: 0;
        // width: 270px;
        padding-bottom: 15px;
        .title-line-ellipsis {
          padding: 0;
        }
      }
      &-content {
        font-family: MicrosoftYaHei-Bold;
        color: #666666;
        font-size: 14px;
        word-break: break-all;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 4; /* 超出几行省略 */
        overflow: hidden;
        line-height: 16px;
        // width: 270px;
        height: 150px;
        background: #eee;
        border-radius: 4px;

        img {
          width: 100%;
          height: 100%;
        }
      }
      &-bottom {
        display: flex;
        font-family: MicrosoftYaHei;
        font-size: 14px;
        color: #999999;
        padding: 15px 0 0px 0;
        height: 62px;

        &-applyValue {
          flex: 1;
        }
        &-visitValue {
          flex: 1;
        }
      }
    }
  }

  .dot-tag {
    display: flex;
    justify-content: center;

    .dot {
      width: 10px;
      height: 10px;
      margin: 5px;
      background-color: #e8e5e5;
      border-radius: 50%;
      cursor: pointer;

      &.active {
        background-color: #2590ff;
      }
    }
  }

  .el-carousel__arrow--left {
    left: 14%;
  }

  .el-carousel__arrow--right {
    right: 14%;
  }

  .el-carousel__arrow[disabled='disabled'] {
    cursor: not-allowed;

    i {
      cursor: not-allowed;
    }

    &:hover {
      background-color: rgba(31, 45, 61, 0.11);
      color: #fff;
    }
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值