• vue移动端下拉刷新、上拉加载


    由于自身的项目比较简单,只有几个H5页面,用来嵌入app中,所有没有引入移动端的UI框架,但是介于能让用户在浏览H5页面时有下拉刷新和上拉加载,有更好的用户体验,自己写组件实现。

    Refresh&Load

    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 {
       100%;
      margin-top: -100px;
      -webkit-overflow-scrolling: touch; /* ios5+ */
    }
    
    .pull-refresh {
       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 {
       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 {
       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 {
       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 {
       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;
       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;
       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;
       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;
       100px;
      height: 98px;
      margin: 40px 42px 0 42px;
    }
    
    .bank-icon {
       56px;
      height: 56px;
      margin: 0 22px 18px;
    }
    
    .bank-name {
      display: flex;
      align-items: center;
       110px;
      height: 24px;
      line-height: 24px;
      font-size: 24px;
      color: #333;
    }
    
    .hot-box {
       100%;
      height: 420px;
      margin-top: 10px;
      background: #fff;
    }
    
    .hot-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
       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;
       11px;
      height: 20px;
      background: url("../../assets/images/bank/more.png") no-repeat;
      background-size: 100%;
    }
    
    .hot-centenrt {
      display: flex;
      align-items: center;
       710px;
      height: 320px;
      margin: 0 20px 20px 20px;
    }
    
    .hot-left {
      display: flex;
      flex-direction: column;
       350px;
      height: 320px;
      background: #f7f7f7;
    }
    
    .left-name {
      display: flex;
      align-items: center;
       282px;
      height: 24px;
      margin: 50px 34px 0 34px;
      font-size: 24px;
      line-height: 24px;
      color: #333;
    }
    
    .left-desc {
      display: flex;
      align-items: center;
       282px;
      height: 20px;
      margin: 12px 34px 0 34px;
      font-size: 20px;
      line-height: 20px;
      color: #999;
    }
    
    .left-img {
       220px;
      height: 142px;
      margin-left: 34px;
      margin-top: 34px;
    }
    
    .hot-right {
      display: flex;
      flex-direction: column;
       350px;
      height: 320px;
      margin-left: 10px;
    }
    
    .right-top {
      display: flex;
      flex-direction: row;
       100%;
      height: 156px;
      background: #f7f7f7;
    }
    
    .text-box {
      display: flex;
      flex-direction: column;
       180px;
      height: 58px;
      margin: 49px 20px 0 20px;
    }
    
    .right-name {
      display: flex;
      align-items: center;
       100%;
      height: 24px;
      line-height: 24px;
      font-size: 24px;
      color: #333;
    }
    
    .right-desc {
      display: flex;
      align-items: center;
      margin-top: 10px;
       100%;
      height: 24px;
      line-height: 24px;
      font-size: 24px;
      color: #999;
    }
    
    .right-img {
       110px;
      height: 70px;
      margin-top: 43px;
    }
    
    .hot-right-bottom {
      display: flex;
      flex-wrap: wrap;
       100%;
      height: 156px;
      margin-top: 8px;
      background: #f7f7f7;
    }
    
    .text-box2 {
      display: flex;
      flex-direction: column;
       180px;
      margin: 31px 20px 0 20px;
    }
    
    .right-name2 {
      display: flex;
      align-items: center;
       100%;
      height: 58px;
      line-height: 30px;
      font-size: 24px;
      color: #333;
    }
    
    .right-desc2 {
      display: flex;
      align-items: center;
      margin-top: 12px;
       100%;
      height: 24px;
      line-height: 24px;
      font-size: 24px;
      color: #999;
    }
    
    .card-state {
      display: flex;
      flex-direction: row;
       100%;
      height: 128px;
      margin-top: 10px;
      background-color: #fff;
    }
    .card-progress {
      display: flex;
      align-items: center;
       327px;
      height: 88px;
      margin: 20px 0 20px 48px;
    }
    .progress-icon {
       48px;
      height: 48px;
      margin: 20px 0;
      background: url("../../assets/images/bank/search.png") no-repeat;
      background-size: 100%;
    }
    .activation-icon {
       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;
       228px;
      height: 66px;
      margin: 11px 20px 11px 30px;
    }
    .card-name {
      display: flex;
      align-items: center;
       100%;
      height: 28px;
      line-height: 28px;
      font-size: 28px;
      color: #333;
    }
    .card-desc {
      display: flex;
      align-items: center;
       100%;
      height: 22px;
      line-height: 22px;
      font-size: 22px;
      margin-top: 16px;
      color: #999;
    }
    .card-activation {
      display: flex;
      align-items: center;
       326px;
      height: 88px;
      margin: 20px 0 20px 48px;
    }
    
    .card-order {
       100%;
      height: auto;
      margin-top: 10px;
      background-color: #fff;
    }
    .border-bottom {
       100%;
      height: 80px;
    }
    .card-list {
       100%;
      height: 228px;
      list-style-type: none;
    }
    .card-content {
      display: flex;
      flex-direction: row;
       700px;
      height: 228px;
      margin-left: 50px;
    }
    .card-img {
       186px;
      height: 120px;
      margin: 54px 0 54px 20px;
    }
    .card-list-text {
      display: flex;
      flex-direction: column;
       386px;
      height: 124px;
      margin: 52px 34px 52px 74px;
    }
    .card-name {
       100%;
      height: 28px;
      line-height: 28px;
      font-size: 28px;
      color: #333;
    }
    .card-title {
       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()方法直接换成接口数据的方法,并将判断的逻辑移到接口方法里,当然根据实际情况,分页呀啥的做做适当的修改。

  • 相关阅读:
    SpringBoot如何使用WebSocket实现前后端交互
    httpx的两个坑(httpx.ReadTimeout; SSL: CERTIFICATE_VERIFY_FAILED)
    力扣744:寻找比目标字母大的最小字母; LeetCode744:Find Smallest Letter Greater Than Target
    【案例】invalid primary checkpoint record
    PG Wal 日志清理
    搭建Grafana+Prometheus监控平台
    一个简单的Dockerfile多阶段构建go项目
    gin框架中的c.Next()/c.Abort()
    java中 抽象类和接口的区别, 什么时候用抽象类?什么时候用接口?
    JetBrains激活和无限试用
  • 原文地址:https://www.cnblogs.com/darkerxi/p/9606402.html
Copyright © 2020-2023  润新知