vue实现pc端无限加载功能

主要思路通过自定义指令,在视图初始化完成后,绑定scroll事件。当scrollTop + clientHeight >= scrollHeight时(此时滚定条到了底部)触发loadMore事件,

<template>
  <div class="index" v-scroll="loadMore">
   <!-- 列表数据传递给子组件,loading表示是否正在加载数据,避免在请求时多次触发 -->
    <my-item :lists="lists" :loading="loading" />
  </div>
</template>

<script>
import MyItem from '~/components/Item.vue'
export default {
  name: 'Index',
  created () {
  // 初始化数据
    this.$store.dispatch('GET_INDEX_LISTS')
    this.lists = this.$store.state.lists
  },
  data() {
    return {
      lists: [],
      page: 1,
      loading: false
    }
  },
  directives: {
  scroll: {
    bind: function (el, binding){
      window.addEventListener('scroll', function() {
        if(document.documentElement.scrollTop + document.documentElement.clientHeight  >= document.documentElement.scrollHeight) {
          let loadData = binding.value
          loadData()
        }
      })
    }
  }
},
methods: {
  async loadMore(){
    if(!this.loading){
      this.loading = true
        // 请求下一页数据
      await this.$store.dispatch('GET_INDEX_LISTS', {
          page: this.page++
        })
    // 重新填充数据
    this.lists = this.lists.concat(this.$store.state.lists)
    this.loading = false
    }
  }
},
  components: {
    MyItem
  }
}
</script>

附上一个css loading动画 , Loading.vue:

<template>
<div class="loading">
  <div class="loader-inner line-scale">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
  </div>
</div>
</template>
<style>
.loading {
  text-align: center;
}
.loader-inner {
  display: inline-block;
}

@-webkit-keyframes line-scale {
  0% {
    -webkit-transform: scaley(1);
    transform: scaley(1);
  }

  50% {
    -webkit-transform: scaley(0.4);
    transform: scaley(0.4);
  }

  100% {
    -webkit-transform: scaley(1);
    transform: scaley(1);
  }
}

@keyframes line-scale {
  0% {
    -webkit-transform: scaley(1);
    transform: scaley(1);
  }

  50% {
    -webkit-transform: scaley(0.4);
    transform: scaley(0.4);
  }

  100% {
    -webkit-transform: scaley(1);
    transform: scaley(1);
  }
}

.line-scale > div:nth-child(1) {
  -webkit-animation: line-scale 1s 0.1s infinite
    cubic-bezier(0.2, 0.68, 0.18, 1.08);
  animation: line-scale 1s 0.1s infinite cubic-bezier(0.2, 0.68, 0.18, 1.08);
}

.line-scale > div:nth-child(2) {
  -webkit-animation: line-scale 1s 0.2s infinite
    cubic-bezier(0.2, 0.68, 0.18, 1.08);
  animation: line-scale 1s 0.2s infinite cubic-bezier(0.2, 0.68, 0.18, 1.08);
}

.line-scale > div:nth-child(3) {
![](http://images2017.cnblogs.com/blog/1027889/201712/1027889-20171206110307066-486062764.png)

  -webkit-animation: line-scale 1s 0.3s infinite
    cubic-bezier(0.2, 0.68, 0.18, 1.08);
  animation: line-scale 1s 0.3s infinite cubic-bezier(0.2, 0.68, 0.18, 1.08);
}

.line-scale > div:nth-child(4) {
  -webkit-animation: line-scale 1s 0.4s infinite
    cubic-bezier(0.2, 0.68, 0.18, 1.08);
  animation: line-scale 1s 0.4s infinite cubic-bezier(0.2, 0.68, 0.18, 1.08);
}

.line-scale > div:nth-child(5) {
  -webkit-animation: line-scale 1s 0.5s infinite
    cubic-bezier(0.2, 0.68, 0.18, 1.08);
  animation: line-scale 1s 0.5s infinite cubic-bezier(0.2, 0.68, 0.18, 1.08);
}

.line-scale > div {
  background-color: #fe0061;
  width: 4px;
  height: 30px;
  border-radius: 2px;
  margin: 2px;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
  display: inline-block;
}
</style>

加载效果图:

posted @ 2017-12-06 11:03  wmui  阅读(2342)  评论(0编辑  收藏  举报