加载更多组件封装vue

1、创建加载更多组件的结构、样式

  •  <template>
       <div class="xtx-infinite-loading" ref="container">
         <div class="loading" v-if="loading">
           <span class="img"></span>
           <span class="text">正在加载...</span>
         </div>
         <div class="none" v-if="finished">
           <span class="img"></span>
           <span class="text">亲,没有更多了</span>
         </div>
       </div>
     </template>
  • <style scoped lang='less'>
    .xtx-infinite-loading {
      .loading {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 200px;
        .img {
          width: 50px;
          height: 50px;
          background: url(../../assets/images/load.gif) no-repeat center / contain;
        }
        .text {
          color: #999;
          font-size: 16px;
        }
      }
      .none {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 200px;
        .img {
          width: 200px;
          height: 134px;
          background: url(../../assets/images/none.png) no-repeat center / contain;
        }
        .text {
          color: #999;
          font-size: 16px;
        }
      }
    }
    </style>

  • loading 默认是 false 是否触底加载

  • finished 默认是 false 是否全部加载完成

2、监听组件是否进入可视区,给父组件派发事件

 <script>
 import { ref } from 'vue'
 import { useIntersectionObserver } from '@vueuse/core'
 export default {
   name: 'XtxInfiniteLoading',
   props: {
     //是否触底加载
     loading: {
       type: Boolean,
       default: false
     },
     //是否全部加载完成
     finished: {
       type: Boolean,
       default: false
     }
   },
   setup (props, { emit }) {
     const container = ref(null)
     // 触底组件是否进入可视区
     useIntersectionObserver(
       container,
       ([{ isIntersecting }], dom) => {
         if (isIntersecting) {
           if (props.loading === false && props.finished === false) {
             //给父组件派发事件,父组件内调用接口API请求数据,渲染页面
             emit('infinite')
           }
         }
       },
       {
         threshold: 0
       }
     )
     return { container }
   }
 }
 </script>

3、父组件内,接受并定义事件

4、当触发事件时

  • loading的值为true

  • 调用接口API

  • 数据返回值赋值合并 list 数组

  • loading的为false

  • 页码++

  • 判断 list.value.length===res.result.counts 时,将 finished 的值改为true,表示完成全部数据的加载,没有更多数据了

5、监听页面路由的变化,当切商品分类时 ( 根据需要,判断路由路径 route.fullPath ),

  • 将 list.value置为空

  • 将loading的值为false

  • 将finished的值为false

  • 将页码的值为1

<template>
    <!-- 加载更多 -->
        <XtxInfiniteLoading :loading="loading" :finished="finished" @infinite="getData" />

</template>
<script>
 import { ref, reactive, watch } from 'vue'
 import { useRoute } from 'vue-router'
   //接口API方法
 import { findSubCategoryGoods } from '@/api/category.js'
 ​
 export default {
   name: 'SubCategory',
   setup () {
     const route = useRoute()
     // 单次接口调用的状态
     const loading = ref(false)
     // 加载完成的标志
     const finished = ref(false)
     // 商品总数
     const total = ref(0)
     // 商品列表
     const list = ref([])
     // 请求参数
     const reqParams = reactive({
       page: 1,
       pageSize: 10
     })
     const getData = () => {
       // 设置接口正在调用
       loading.value = true
       findSubCategoryGoods(reqParams).then(ret => {
         // 把本次加载的数据追加到列表中
         list.value.push(...ret.result.items)
         // 获取商品列表的总数
         total.value = ret.result.counts
         // 本次接口调用完成
         loading.value = false
         if (list.value.length === total.value && total.value !== 0) {
           // 没有更多数据了
           finished.value = true
         }
         // 页码需要累加
         reqParams.page += 1
       })
     }
      // 如果二级分类发生变化,重置当前的数据
     watch(() => route.params.id, (newVal) => {
       // 判断是否为二级分类
       if (route.fullPath !== '/category/sub/' + newVal) return
       // 重置数据
       list.value = []
       total.value = 0
       loading.value = false
       finished.value = false
       reqParams.page = 1
     })
 ​
     return { loading, finished, getData, list }
   }
 }
 </script>
 ​
     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值