vue原生下拉刷新,上滑加载,延迟加载,预加载

这是一个关于Vue.js组件的实现,主要功能包括加载更多汽车列表和图片预加载。组件中,当用户滚动到页面底部时,会触发加载更多汽车列表,并通过异步调用获取新的数据。同时,图片预加载策略确保了图片在显示前已经加载完成,提高了用户体验。此外,还使用了触摸事件来处理滚动操作,并有加载动画效果。
摘要由CSDN通过智能技术生成
<template>
  <div class="load-more">
    <div class="load-more-loading">
      <!-- <img src='./../assets/image/loading.gif'> -->
    </div>
    <div
      ref="loadMore"
      @touchstart="FnStart"
      @touchmove="FnMove"
      @touchend="FnEnd"
      class="load-more-list"
    >
      <div
        class="load-more-car"
        v-for="item in CarList"
        :key="item.ID"
      >
        <div class="load-more-item">
          <div class="load-more-left">
            <img
              class="load-more-kmr"
              :src="`${ImageState(item)}`"
              alt="ft_kmr.jpg"
            />
          </div>
          <div class="load-more-right">
            <div class="load-more-title">{{item.tit_con}}</div>
            <div class="load-more-information">
              <div class="load-more-year">{{item.buy_time}}</div>
              <div class="load-more-line"></div>
              <div class="load-more-kilometre">{{item.kilometre}}万公里</div>
            </div>
          </div>
        </div>
  </div>
  </div>
  <div
    v-if="LoadingInit"
    class="shadow"
    @touchmove.prevent
  >
    <div class="loading">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    </div>
    </div>
</template>

<script>
import { getCarList } from "@/api";
export default {
  name: "LoadMore",
  data() {
    return {
      CarList: [],
      LoadingInit: true,
      CarCount: 0,
      ImageList: [],
      ImageCount: 0,
      LoadingMore: true,
      LoadingPage: 1
    };
  },
  async created() {},
  methods: {
    async GetCarList() {
      this.CarList = await getCarList({ page: this.LoadingPage });
    },
    async FnInit(){
      
      // 接口数据的重新加载
      await this.GetCarList();

      this.ViewHeight = document.documentElement.clientHeight;
      this.ScrollTop =
        document.documentElement.scorllTop || document.body.scrollTop;

      this.EveryHeight =
        this.$refs["loadMore"].scrollHeight / this.CarList.length;
      // 所有的数据设置高度
      this.FnSetHeight(1);

      this.ImageList.push("http://www.ibugthree.com/default.gif");
      for (let i = 0; i < this.ImageList.length; i++) {
        let oImage = new Image();
        let URL = this.ImageList[i];

        oImage.src = URL;
        oImage.onload = () => {
          this.ImageCount++;
          if (this.ImageCount >= this.ImageList.length) {
            // 数据加载完成loading 动画消失
            this.LoadingInit = false;
          }
        };
      }
    },
    FnInitData(){
      this.CarList=[],
      this.LoadingInit=true,
      this.CarCount=0,
      this.ImageList=[],
      this.ImageCount=0,
      this.LoadingMore=true,
      this.LoadingPage=1
    },
    FnStart(ev){
      this.$refs["loadMore"].classList.remove('active');
      this.startY=ev.changedTouches[0].pageY
      this.PageY=this.startY-this.$refs["loadMore"].getBoundingClientRect().top;

    },
    FnMove(ev){
      this.moveY=ev.changedTouches[0].pageY;
      if(this.moveY>this.startY && this.ScrollTop==0){
        this.Y=this.moveY-this.PageY;
        this.scale=1-this.Y/736;
        if(this.scale<=.58)this.scale=.58;
        this.$refs["loadMore"].style.transform=`translate(0,${this.Y*this.scale}px)`;  
        ev.preventDefault && ev.preventDefault();
      } 

      

    },
    async FnEnd(ev){

      this.UpY=ev.changedTouches[0].pageY;
      this.$refs["loadMore"].classList.add('active');
      this.$refs["loadMore"].style.transform=`translate(0,0)`;
      
      if(this.UpY>this.startY && this.ScrollTop==0){
      // 所有的数据恢复之前状态
        this.FnInitData();
        // 图片预加载 设置高度
        await this.FnInit(); 
      }

    },
    FnSetHeight(whether) {
      for (let i = 0; i < this.CarList.length; i++) {
        let json = this.CarList[i];

        this.CarCount = this.EveryHeight * i;
        json.height = this.CarCount;

        if (this.CarCount > this.ViewHeight) {
          // 这些都是不需要加载出来的
          json.imageState = 0;
        } else {
          // 需要加载的出来的图片
          json.imageState = 1;
          if(whether){
            // 是否需要添加图片
            let URL = `http://www.ibugthree.com/${json.img_src}`;
            this.ImageList.push(URL);          
          }
          
        }
        // 求出每个数据的高度
      }
    },
    async FnDelayedLoad() {
      // 延迟加载
      this.ScrollTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      this.ScrollHeight = this.ScrollTop + this.ViewHeight;

      for (let i = 0; i < this.CarList.length; i++) {
        let Car = this.CarList[i];
        if (this.ViewHeight + this.ScrollTop > Car.height) {
          Car.imageState = 1;

          this.$set(this.CarList, i, Car);
        }
      }
      // 加载更多
      if (this.ScrollHeight >= this.$refs["loadMore"].scrollHeight) {
        if (this.LoadingMore) {
          this.LoadingMore = false; //执行完成一次就不能执行
          this.LoadingPage++;

          let CarData = await getCarList({ page: this.LoadingPage });

          this.CarList = this.CarList.concat(CarData);
          this.LoadingMore = true; // 等到数据加载完成后,再次重新执行

          // 所有的数据设置高度
          this.FnSetHeight();
        }
      }
    },
    ImageState(item) {
      if (item.imageState) {
        return `http://www.ibugthree.com/${item.img_src}`;
      } else {
        return `http://www.ibugthree.com/default.gif`;
      }
    }
  },
  async mounted() {
    // 预加载部分
    await this.FnInit();
    // 监听整个页面滚动事件
    document.onscroll = this.FnDelayedLoad;
  }
  // 图片预加载
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.load-more {
  position:relative;
  .load-more-loading{
    width:100px;
    height:100px;
    background:url(./../assets/image/loading.gif);
    background-size:cover;
    position:absolute;
    left:0;
    right:0;
    margin:auto;
    top:30px;
  }
  .shadow {
    width: 100vw;
    height: 100vh;
    position: fixed;
    left: 0;
    top: 0;
    background: #fff;
    .loading {
      width: 100px;
      height: 40px;
      margin: 0 auto;
      margin-top: 100px;
    }
    .loading span {
      display: inline-block;
      width: 8px;
      height: 100%;
      border-radius: 4px;
      background: lightgreen;
      -webkit-animation: load 1s ease infinite;
      margin: 0 3px 0 3px;
    }
    @-webkit-keyframes load {
      0%,
      100% {
        height: 40px;
        background: lightgreen;
      }
      50% {
        height: 70px;
        margin: -15px 0;
        background: lightblue;
      }
    }
    .loading span:nth-child(2) {
      -webkit-animation-delay: 0.2s;
    }
    .loading span:nth-child(3) {
      -webkit-animation-delay: 0.4s;
    }
    .loading span:nth-child(4) {
      -webkit-animation-delay: 0.6s;
    }
    .loading span:nth-child(5) {
      -webkit-animation-delay: 0.8s;
    }
  }
  .load-more-list.active{
    transition:.25s ease-in all;
  }
  .load-more-list {
    background:#fff;
    position:relative;
    z-index:2;
    .load-more-car::after {
      display: block;
      content: "";
      width: 723px;
      height: 1px;
      background: #ededed;
      position: absolute;
      right: 0;
      margin: 42px 0 29px 0;
    }
    .load-more-car {
      position: relative;
      height: 230px;
      padding: 29px 0 0 0;
      .load-more-item {
        display: flex;
        flex-wrap: wrap;
        .load-more-left {
          padding: 0 0 0 14px;
          width: 249px;
          height: 187px;
          .load-more-kmr {
            width: 249px;
            height: 187px;
            border-radius: 10px;
          }
        }
        .load-more-right {
          padding: 0 0 0 19px;
          .load-more-title {
            width: 426px;
            font-size: 27px;
            color: #000;
            font-weight: bold;
          }
          .load-more-information {
            display: flex;
            color: #ababab;
            font-size: 19px;
            line-height: 19px;
            padding: 11px 0 0 0;
            .load-more-line {
              width: 3px;
              height: 19px;
              background: #ababab;
              margin: 0px 7px 0 8px;
            }
          }
        }
      }
    }
  }
}
</style>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值