天天看點

vue移動端下拉重新整理、上拉加載

由于自身的項目比較簡單,隻有幾個H5頁面,用來嵌入app中,所有沒有引入移動端的UI架構,但是介于能讓使用者在浏覽H5頁面時有下拉重新整理和上拉加載,有更好的使用者體驗,自己寫元件實作。

vue移動端下拉重新整理、上拉加載
1、下拉重新整理

DropDownRefresh.vue

<template lang="html">
    <div class="refresh-moudle" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)" :style="{transform: 'translate3d(0,' + top + 'px, 0)'}">
      <header class="pull-refresh">
        <slot name="pull-refresh">
          <div class="down-tip" v-if="dropDownState==1">
            <img v-if="dropDownInfo.downImg" class="down-img" :src="require('../../assets/images/refreshAndReload/'+dropDownInfo.downImg)">
            <span class="down-text">{{dropDownInfo.downText}}</span>
          </div>
          <div class="up-tip" v-if="dropDownState==2">
            <img v-if="dropDownInfo.upImg" class="up-img" :src="require('../../assets/images/refreshAndReload/'+dropDownInfo.upImg)">
            <span class="up-text">{{dropDownInfo.upText}}</span>
          </div>
          <div class="refresh-tip" v-if="dropDownState==3">
            <img v-if="dropDownInfo.refreshImg" class="refresh-img" :src="require('../../assets/images/loading/'+dropDownInfo.refreshImg)">
            <span class="refresh-text">{{dropDownInfo.refreshText}}</span>
          </div>
        </slot>
      </header>
      <slot></slot>
    </div>
</template>
<script>
export default {
  props: {
    onRefresh: {
      type: Function,
      required: false
    }
  },
  data () {
    return {
      defaultOffset: 50, // 預設高度, 相應的修改.releshMoudle的margin-top和.down-tip, .up-tip, .refresh-tip的height
      top: 0,
      scrollIsToTop: 0,
      startY: 0,
      isDropDown: false, // 是否下拉
      isRefreshing: false, // 是否正在重新整理
      dropDownState: 1, // 顯示1:下拉可以重新整理, 2:松開立即重新整理, 3:正在重新整理資料中...
      dropDownInfo: {
        downText: '下拉可以重新整理',
        downImg: 'arrow.png',
        upText: '松開立即重新整理',
        upImg: 'arrow.png',
        refreshText: '正在重新整理資料...',
        refreshImg: 'loading.png'
      }
    }
  },
  created () {
    if (document.querySelector('.down-tip')) {
      // 擷取不同手機的實體像素(dpr),以便适配rem
      this.defaultOffset = document.querySelector('.down-tip').clientHeight || this.defaultOffset
    }
  },
  methods: {
    /**
     * 觸摸開始,手指點選螢幕時
     * @param {object} e Touch 對象包含的屬性
     */
    touchStart (e) {
      this.startY = e.targetTouches[0].pageY
    },

    /**
     * 接觸點改變,滑動時
     * @param {object} e Touch 對象包含的屬性
     */
    touchMove (e) {
      this.scrollIsToTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop // safari 擷取scrollTop用window.pageYOffset
      if (e.targetTouches[0].pageY > this.startY) {
        // 下拉
        this.isDropDown = true
        if (this.scrollIsToTop === 0 && !this.isRefreshing) {
          // 拉動的距離
          let diff = e.targetTouches[0].pageY - this.startY - this.scrollIsToTop
          this.top = Math.pow(diff, 0.8) + (this.dropDownState === 3 ? this.defaultOffset : 0)
          if (this.top >= this.defaultOffset) {
            this.dropDownState = 2
            e.preventDefault()
          } else {
            this.dropDownState = 1
            // 去掉會導緻ios無法重新整理
            e.preventDefault()
          }
        }
      } else {
        this.isDropDown = false
        this.dropDownState = 1
      }
    },

    /**
     * 觸摸結束,手指離開螢幕時
     * @param {object} e Touch 對象包含的屬性
     */
    touchEnd (e) {
      if (this.isDropDown && !this.isRefreshing) {
        if (this.top >= this.defaultOffset) {
          // do refresh
          this.refresh()
          this.isRefreshing = true
        } else {
          // cancel refresh
          this.isRefreshing = false
          this.isDropDown = false
          this.dropDownState = 1
          this.top = 0
        }
      }
    },

    /**
     * 重新整理
     */
    refresh () {
      this.dropDownState = 3
      this.top = this.defaultOffset
      // 這是全是靜态資料,延時1200毫秒,給使用者一個重新整理的感覺,如果是接口資料的話,直接調接口即可
      setTimeout(() => {
        this.onRefresh(this.refreshDone)
      }, 1200)
    },

    /**
     * 重新整理完成
     */
    refreshDone () {
      this.isRefreshing = false
      this.isDropDown = false
      this.dropDownState = 1
      this.top = 0
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.refresh-moudle {
  width: 100%;
  margin-top: -100px;
  -webkit-overflow-scrolling: touch; /* ios5+ */
}

.pull-refresh {
  width: 100%;
  color: #999;
  transition-duration: 200ms;
  font-size: 24px;
}

.refresh-moudle .down-tip,
.up-tip,
.refresh-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100px;
}

.down-img {
  width: 35px;
  height: 35px;
  margin-right: 15px;
  transform: rotate(0deg);
  animation: anticlockwise 0.8s ease;
}

@keyframes anticlockwise {
  0% {
    transform: rotate(-180deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

.up-img {
  width: 35px;
  height: 35px;
  margin-right: 15px;
  transform: rotate(180deg);
  animation: clockwise 0.8s ease;
}

@keyframes clockwise {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(-180deg);
  }
}

.refresh-img {
  width: 35px;
  height: 35px;
  margin-right: 15px;
  animation: rotating 1.5s linear infinite;
}

@keyframes rotating {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(1turn);
  }
}
</style>
           
2、上拉加載

PullUpReload.vue

<template lang="html">
  <div class="load-moudle" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchend($event)">
    <slot></slot>
    <footer class="load-more">
      <slot name="load-more">
        <div class="more-tip" v-if="pullUpState==1">
          <span class="more-text">{{pullUpInfo.moreText}}</span>
        </div>
        <div class="loading-tip" v-if="pullUpState==2">
          <span class="loading-icon"></span>
          <span class="loading-text">{{pullUpInfo.loadingText}}</span>
        </div>
        <div class="no-more-tip" v-if="pullUpState==3">
          <span class="connecting-line"></span>
          <span class="no-more-text">{{pullUpInfo.noMoreText}}</span>
          <span class="connecting-line"></span>
        </div>
      </slot>
    </footer>
  </div>
</template>

<script>
export default {
  props: {
    parentPullUpState: {
      default: 0
    },
    onInfiniteLoad: {
      type: Function,
      require: false
    }
  },
  data () {
    return {
      top: 0,
      pullUpState: 0, // 1:上拉加載更多, 2:加載中……, 3:我是有底線的
      isLoading: false, // 是否正在加載
      pullUpInfo: {
        moreText: '上拉加載更多',
        loadingText: '資料加載中...',
        noMoreText: '我是有底線的'
      },
      startX: 0,
      startY: 0,
      endX: 0,
      endY: 0
    }
  },
  methods: {
    /**
     * 觸摸開始,手指點選螢幕時
     * @param {object} e Touch 對象包含的屬性
     */
    touchStart (e) {
      this.startX = e.touches[0].pageX
      this.startY = e.touches[0].pageY
    },

    /**
     * 接觸點改變,滑動時
     * @param {object} e Touch 對象包含的屬性
     */
    touchMove (e) {
      this.endX = e.changedTouches[0].pageX
      this.endY = e.changedTouches[0].pageY
      let direction = this.getSlideDirection(this.startX, this.startY, this.endX, this.endY)
      switch (direction) {
        case 0:
          // console.log('沒滑動')
          break
        case 1:
          // console.log('向上')
          this.scrollToTheEnd()
          break
        case 2:
          // console.log('向下')
          break
        case 3:
          // console.log('向左')
          break
        case 4:
          // console.log('向右')
          break
        default:
      }
    },

    /**
     * 觸摸結束,手指離開螢幕時
     * @param {object} e Touch 對象包含的屬性
     */
    touchend (e) {
      this.isLoading = false
    },

    /**
     * 判斷滾動條是否到底
     */
    scrollToTheEnd () {
      let innerHeight = document.querySelector('.load-moudle').clientHeight
      // 變量scrollTop是滾動條滾動時,距離頂部的距離
      let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
      // 變量scrollHeight是滾動條的總高度
      let scrollHeight = document.documentElement.clientHeight || document.body.scrollHeight
      // 滾動條到底部的條件
      if (scrollTop + scrollHeight >= innerHeight) {
        if (this.pullUpState !== 3 && !this.isLoading) {
          this.infiniteLoad()
        }
        // console.log('距頂部' + scrollTop + '滾動條總高度' + scrollHeight + '内容高度' + innerHeight)
      }
    },

    /**
     * 上拉加載資料
     */
    infiniteLoad () {
      if (this.pullUpState !== 0) {
        this.pullUpState = 2
        this.isLoading = true
        this.onInfiniteLoad(this.infiniteLoadDone)
      }
    },

    /**
     * 加載資料完成
     */
    infiniteLoadDone () {
      this.pullUpState = 1
    },

    /**
     * 傳回角度
     */
    getSlideAngle (dx, dy) {
      return Math.atan2(dy, dx) * 180 / Math.PI
    },

    /**
     * 根據起點和終點傳回方向 1:向上,2:向下,3:向左,4:向右,0:未滑動
     * @param {number} startX X軸開始位置
     * @param {number} startY X軸結束位置
     * @param {number} endX Y軸開始位置
     * @param {number} endY Y軸結束位置
     */
    getSlideDirection (startX, startY, endX, endY) {
      let dy = startY - endY
      let dx = endX - startX
      let result = 0
      // 如果滑動距離太短
      if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
        return result
      }
      let angle = this.getSlideAngle(dx, dy)
      if (angle >= -45 && angle < 45) {
        result = 4
      } else if (angle >= 45 && angle < 135) {
        result = 1
      } else if (angle >= -135 && angle < -45) {
        result = 2
      } else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
        result = 3
      }
      return result
    }
  },
  watch: {
    parentPullUpState (curVal, oldVal) {
      this.pullUpState = curVal
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.load-more {
  width: 100%;
  color: #c0c0c0;
  background: #fafafa;
  font-size: 24px;
}

.more-tip,
.loading-tip,
.no-more-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 150px;
}

.load-moudle .loading-icon {
  display: inline-flex;
  width: 35px;
  height: 35px;
  background: url(../../assets/images/refreshAndReload/loading.png) no-repeat;
  background-size: cover;
  margin-right: 5px;
  animation: rotating 2s linear infinite;
}

@keyframes rotating {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(1turn);
  }
}

.connecting-line {
  display: inline-flex;
  width: 150px;
  height: 2px;
  background: #ddd;
  margin-left: 20px;
  margin-right: 20px;
}
</style>
           
3、對兩個元件的使用
<template>
  <section class="container">
    <v-refresh :on-refresh="onRefresh">
      <v-reload
        :on-infinite-load="onInfiniteLoad"
        :parent-pull-up-state="infiniteLoadData.pullUpState"
      >
        <div class="bank-box">
          <div class="bank-list" v-for="item in bankList" :key="item.id">
            <div
              class="bank-icon"
              :style="{ 'background': 'url(' + require('../../assets/images/bankIcon/'+item.iconName) + ') no-repeat', 'background-size': '100%' }"
            ></div>
            <span class="bank-name">{{item.bankName}}</span>
          </div>
        </div>
        <div class="hot-box">
          <div class="hot-header">
            <span class="hot-name">熱門推薦</span>
            <div class="more-box">
              <span class="more-text">檢視更多</span>
              <span class="more-icon"></span>
            </div>
          </div>
          <div class="hot-centenrt">
            <div class="hot-left">
              <span class="left-name">{{hotLeft.name}}</span>
              <span class="left-desc">{{hotLeft.desc}}</span>
              <div
                class="left-img"
                :style="{ 'background': 'url(' + require('../../assets/images/bank/'+hotLeft.imgName) + ') no-repeat', 'background-size': '100%' }"
              ></div>
            </div>
            <div class="hot-right">
              <div class="right-top">
                <div class="text-box">
                  <span class="right-name">{{centenrtOne.name}}</span>
                  <span class="right-desc">{{centenrtOne.desc}}</span>
                </div>
                <div
                  class="right-img"
                  :style="{ 'background': 'url(' + require('../../assets/images/bank/'+centenrtOne.imgName) + ') no-repeat', 'background-size': '100%' }"
                ></div>
              </div>
              <div class="hot-right-bottom">
                <div class="text-box2">
                  <span class="right-name2">{{centenrtTwo.name}}</span>
                  <span class="right-desc2">{{centenrtTwo.desc}}</span>
                </div>
                <div
                  class="right-img"
                  :style="{ 'background': 'url(' + require('../../assets/images/bank/'+centenrtTwo.imgName) + ') no-repeat', 'background-size': '100%' }"
                ></div>
              </div>
            </div>
          </div>
        </div>
        <div class="card-state">
          <div class="card-progress border-right">
            <div class="progress-icon"></div>
            <div class="card-text">
              <span class="card-name">辦卡進度</span>
              <span class="card-desc">讓等待随處可見</span>
            </div>
          </div>
          <div class="card-activation">
            <div class="activation-icon"></div>
            <div class="card-text">
              <span class="card-name">辦卡激活</span>
              <span class="card-desc">讓等待随處可見</span>
            </div>
          </div>
        </div>
        <div class="card-order">
          <div class="border-bottom card-bottom">
            <div class="hot-header">
              <span class="hot-name">熱卡排行</span>
            </div>
          </div>
          <div slot="load-more">
            <li
              class="card-list"
              v-for="(item,index) in infiniteLoadData.pullUpList"
              :key="item.id"
            >
              <div
                class="card-content"
                :class="infiniteLoadData.pullUpList.length - 1 != index? 'card-bottom':''"
              >
                <div
                  class="card-img"
                  :style="{ 'background': 'url(' + require('../../assets/images/bank/'+item.imgName) + ') no-repeat', 'background-size': '100%' }"
                ></div>
                <div class="card-list-text">
                  <p class="card-name">{{item.cardName}}</p>
                  <p class="card-title">{{item.cardTitle}}</p>
                  <div class="words-lists">
                    <div class="card-words">
                      <p class="card-word">{{item.cardWordOne}}</p>
                    </div>
                    <div v-if="item.cardWordTwo" class="card-words words-two">
                      <p class="card-word">{{item.cardWordTwo}}</p>
                    </div>
                  </div>
                </div>
              </div>
            </li>
          </div>
        </div>
      </v-reload>
    </v-refresh>
  </section>
</template>

<script>
import DropDownRefresh from '../common/DropDownRefresh'
import PullUpReload from '../common/PullUpReload'
export default {
  data () {
    return {
      bankList: [
        {
          iconName: 'zhaoshang.png',
          bankName: '招商銀行'
        },
        {
          iconName: 'minsheng.png',
          bankName: '民生銀行'
        },
        {
          iconName: 'pingancar.png',
          bankName: '平安聯名'
        },
        {
          iconName: 'xingye.png',
          bankName: '興業銀行'
        },
        {
          iconName: 'shanghai.png',
          bankName: '上海銀行'
        },
        {
          iconName: 'jiaotong.png',
          bankName: '交通銀行'
        },
        {
          iconName: 'guangda.png',
          bankName: '光大銀行'
        },
        {
          iconName: 'more.png',
          bankName: '全部銀行'
        }
      ],
      hotLeft: {
        bankName: '交通銀行',
        name: '交行Y-POWER黑卡',
        desc: '額度100%取現',
        imgName: 'jiaohangY-POWER.png'
      },
      centenrtOne: {
        bankName: '招商銀行',
        name: '招行YOUNG卡',
        desc: '生日月雙倍積分',
        imgName: 'zhaohangYOUNG.png'
      },
      centenrtTwo: {
        bankName: '光大銀行',
        name: '光大淘票票公仔聯名卡',
        desc: '電影達人必備',
        imgName: 'guangdalianming.png'
      },
      cardList: [
        {
          bankName: '平安聯名',
          imgName: 'pinganqiche.png',
          cardName: '平安銀行信用卡',
          cardTitle: '平安銀行汽車之家聯名單币卡',
          cardWordOne: '首年免年費',
          cardWordTwo: '加油88折'
        },
        {
          bankName: '上海銀行',
          imgName: 'shanghaitaobao.png',
          cardName: '上海銀行信用卡',
          cardTitle: '淘寶金卡',
          cardWordOne: '積分抵現',
          cardWordTwo: '首刷有禮'
        },
        {
          bankName: '華夏銀行',
          imgName: 'huaxiaiqiyi.png',
          cardName: '華夏銀行信用卡',
          cardTitle: '華夏愛奇藝悅看卡',
          cardWordOne: '送愛奇藝會員',
          cardWordTwo: '商城8折'
        },
        {
          bankName: '浦發銀行',
          imgName: 'pufajianyue.png',
          cardName: '浦發銀行信用卡',
          cardTitle: '浦發銀行簡約白金卡',
          cardWordOne: '團購立減',
          cardWordTwo: '酒店優惠 免年費'
        },
        {
          bankName: '中信銀行',
          imgName: 'zhongxinbaijin.png',
          cardName: '中信銀行信用卡',
          cardTitle: '中信銀行i白金信用卡',
          cardWordOne: '首刷有禮',
          cardWordTwo: '雙倍積分'
        }
      ],
      // 上拉加載的設定
      infiniteLoadData: {
        initialShowNum: 3, // 初始顯示多少條
        everyLoadingNum: 3, // 每次加載的個數
        pullUpState: 2, // 子元件的pullUpState狀态
        pullUpList: [], // 上拉加載更多資料的數組
        showPullUpListLength: this.initialShowNum // 上拉加載後所展示的個數
      }
    }
  },
  mounted () {
    this.getStartPullUpState()
    this.getPullUpDefData()
  },
  methods: {
    /**
     * 擷取上拉加載的初始資料
     */
    getPullUpDefData () {
      this.infiniteLoadData.pullUpList = []
      if (this.cardList.length < this.infiniteLoadData.initialShowNum) {
        for (let i = 0; i < this.cardList.length; i++) {
          this.infiniteLoadData.pullUpList.push(this.cardList[i])
        }
      } else {
        for (let i = 0; i < this.infiniteLoadData.initialShowNum; i++) {
          this.infiniteLoadData.pullUpList.push(this.cardList[i])
        }
      }
      this.getStartPullUpState()
    },

    /**
     * 擷取上拉加載的pullUpState狀态
     */
    getStartPullUpState () {
      if (this.infiniteLoadData.pullUpList.length) {
        if (this.cardList.length <= this.infiniteLoadData.initialShowNum) {
          // 修改子元件的pullUpState狀态
          this.infiniteLoadData.pullUpState = 3
        } else {
          this.infiniteLoadData.pullUpState = 1
        }
      } else {
        this.infiniteLoadData.pullUpState = 0
      }
    },

    /**
     * 上拉一次加載更多的資料
     */
    getPullUpMoreData () {
      this.showPullUpListLength = this.infiniteLoadData.pullUpList.length
      if (this.infiniteLoadData.pullUpList.length + this.infiniteLoadData.everyLoadingNum > this.cardList.length) {
        for (let i = 0; i < this.cardList.length - this.showPullUpListLength; i++) {
          this.infiniteLoadData.pullUpList.push(this.cardList[i + this.showPullUpListLength])
        }
      } else {
        for (let i = 0; i < this.infiniteLoadData.everyLoadingNum; i++) {
          this.infiniteLoadData.pullUpList.push(this.cardList[i + this.showPullUpListLength])
        }
      }
      if (this.cardList.length === this.infiniteLoadData.pullUpList.length) {
        this.infiniteLoadData.pullUpState = 3
      } else {
        this.infiniteLoadData.pullUpState = 1
      }
    },

    /**
     * 下拉重新整理
     */
    onRefresh (done) {
      // 如果下拉重新整理和上拉加載同時使用,下拉時初始化上拉的資料
      this.getStartPullUpState()
      this.getPullUpDefData()
      done() // call done
    },

    /**
     * 上拉加載
     */
    onInfiniteLoad (done) {
      if (this.infiniteLoadData.pullUpState === 1) {
        this.getPullUpMoreData()
      }
      done()
    }
  },
  components: {
    'v-refresh': DropDownRefresh,
    'v-reload': PullUpReload
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
@import "../../assets/css/not2rem.css";
.container {
  display: flex;
  flex-direction: column;
  width: 750px;
  height: 1334px;
  background-color: #f7f7f7;
}

.bank-box {
  display: flex;
  flex-wrap: wrap;
  padding: 2px 7px 42px 7px;
  background-color: #fff;
}

.bank-list {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100px;
  height: 98px;
  margin: 40px 42px 0 42px;
}

.bank-icon {
  width: 56px;
  height: 56px;
  margin: 0 22px 18px;
}

.bank-name {
  display: flex;
  align-items: center;
  width: 110px;
  height: 24px;
  line-height: 24px;
  font-size: 24px;
  color: #333;
}

.hot-box {
  width: 100%;
  height: 420px;
  margin-top: 10px;
  background: #fff;
}

.hot-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 674px;
  height: 80px;
  margin: 0 30px 0 46px;
}

.hot-name {
  display: flex;
  align-items: center;
  height: 28px;
  font-size: 28px;
  color: #333;
}

.more-text {
  display: flex;
  align-items: center;
  font-size: 24px;
  color: #999;
}

.more-box {
  display: flex;
  align-items: center;
}

.more-icon {
  margin-left: 20px;
  width: 11px;
  height: 20px;
  background: url("../../assets/images/bank/more.png") no-repeat;
  background-size: 100%;
}

.hot-centenrt {
  display: flex;
  align-items: center;
  width: 710px;
  height: 320px;
  margin: 0 20px 20px 20px;
}

.hot-left {
  display: flex;
  flex-direction: column;
  width: 350px;
  height: 320px;
  background: #f7f7f7;
}

.left-name {
  display: flex;
  align-items: center;
  width: 282px;
  height: 24px;
  margin: 50px 34px 0 34px;
  font-size: 24px;
  line-height: 24px;
  color: #333;
}

.left-desc {
  display: flex;
  align-items: center;
  width: 282px;
  height: 20px;
  margin: 12px 34px 0 34px;
  font-size: 20px;
  line-height: 20px;
  color: #999;
}

.left-img {
  width: 220px;
  height: 142px;
  margin-left: 34px;
  margin-top: 34px;
}

.hot-right {
  display: flex;
  flex-direction: column;
  width: 350px;
  height: 320px;
  margin-left: 10px;
}

.right-top {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 156px;
  background: #f7f7f7;
}

.text-box {
  display: flex;
  flex-direction: column;
  width: 180px;
  height: 58px;
  margin: 49px 20px 0 20px;
}

.right-name {
  display: flex;
  align-items: center;
  width: 100%;
  height: 24px;
  line-height: 24px;
  font-size: 24px;
  color: #333;
}

.right-desc {
  display: flex;
  align-items: center;
  margin-top: 10px;
  width: 100%;
  height: 24px;
  line-height: 24px;
  font-size: 24px;
  color: #999;
}

.right-img {
  width: 110px;
  height: 70px;
  margin-top: 43px;
}

.hot-right-bottom {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: 156px;
  margin-top: 8px;
  background: #f7f7f7;
}

.text-box2 {
  display: flex;
  flex-direction: column;
  width: 180px;
  margin: 31px 20px 0 20px;
}

.right-name2 {
  display: flex;
  align-items: center;
  width: 100%;
  height: 58px;
  line-height: 30px;
  font-size: 24px;
  color: #333;
}

.right-desc2 {
  display: flex;
  align-items: center;
  margin-top: 12px;
  width: 100%;
  height: 24px;
  line-height: 24px;
  font-size: 24px;
  color: #999;
}

.card-state {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 128px;
  margin-top: 10px;
  background-color: #fff;
}
.card-progress {
  display: flex;
  align-items: center;
  width: 327px;
  height: 88px;
  margin: 20px 0 20px 48px;
}
.progress-icon {
  width: 48px;
  height: 48px;
  margin: 20px 0;
  background: url("../../assets/images/bank/search.png") no-repeat;
  background-size: 100%;
}
.activation-icon {
  width: 48px;
  height: 48px;
  margin: 20px 0;
  background: url("../../assets/images/bank/activation.png") no-repeat;
  background-size: 100%;
}
.card-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 228px;
  height: 66px;
  margin: 11px 20px 11px 30px;
}
.card-name {
  display: flex;
  align-items: center;
  width: 100%;
  height: 28px;
  line-height: 28px;
  font-size: 28px;
  color: #333;
}
.card-desc {
  display: flex;
  align-items: center;
  width: 100%;
  height: 22px;
  line-height: 22px;
  font-size: 22px;
  margin-top: 16px;
  color: #999;
}
.card-activation {
  display: flex;
  align-items: center;
  width: 326px;
  height: 88px;
  margin: 20px 0 20px 48px;
}

.card-order {
  width: 100%;
  height: auto;
  margin-top: 10px;
  background-color: #fff;
}
.border-bottom {
  width: 100%;
  height: 80px;
}
.card-list {
  width: 100%;
  height: 228px;
  list-style-type: none;
}
.card-content {
  display: flex;
  flex-direction: row;
  width: 700px;
  height: 228px;
  margin-left: 50px;
}
.card-img {
  width: 186px;
  height: 120px;
  margin: 54px 0 54px 20px;
}
.card-list-text {
  display: flex;
  flex-direction: column;
  width: 386px;
  height: 124px;
  margin: 52px 34px 52px 74px;
}
.card-name {
  width: 100%;
  height: 28px;
  line-height: 28px;
  font-size: 28px;
  color: #333;
}
.card-title {
  width: 100%;
  height: 24px;
  margin-top: 20px;
  line-height: 24px;
  font-size: 24px;
  color: #666;
}
.words-lists {
  display: flex;
  flex-direction: row;
}
.card-words {
  height: 36px;
  margin-top: 16px;
  border-radius: 20px;
  background-color: #e8ca88;
}
.card-word {
  height: 20px;
  padding: 8px 18px;
  line-height: 20px;
  font-size: 20px;
  color: #4b4b4b;
}
.words-two {
  margin-left: 20px;
}
</style>
           

這裡隻是展示了一下效果,使用的全是靜态資料,如果要用接口資料的話,

this.getPullUpMoreData()

方法直接換成接口資料的方法,并将判斷的邏輯移到接口方法裡,當然根據實際情況,分頁呀啥的做做适當的修改。