使用vue $emit和$on 封装滚动到底加载刷新

每个 Vue 实例都实现了事件接口:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件
    一旦 $emit 事件触发 $on 则监听到 $emit 所派发的事件,派发出的命令和执行派执命令所要做的事都是一一对应的。
//滑动触底加载组件 scrollLower.vue
<template>
  <div>
    <slot name="list"></slot>
    <div v-show="!isLoading && isDone">
      <slot>没有更多数据了</slot>
    </div>
    <div v-show="isLoading">
      <slot>加载中</slot>
    </div>
  </div>
</template>

<script>
export default {
  props: {
  //父组件传递方法
    onScroll: {
      type: Function,
      required: true
    },
  },
  data() {
    return {
      isLoading: false, //false表示加载更多,true表示加载完毕
      isDone: false //false代表数据没有完全加载完毕
    };
  },
  methods: {
    init() {
      this.$on("loadedDone", () => {
        this.isLoading = false;
        this.isDone = true;
      });
      //恢复可加载状态
      this.$on("finishLoading", () => {
        console.log("fhdjfdj");
        this.isLoading = true;
      });
    },
    //获取ScrollTop
    getScrollTop() {
      var scrollTop = 0,bodyScrollTop = 0,documentScrollTop = 0;
      if (document.body) {
        bodyScrollTop = document.body.scrollTop;
      }
      if (document.documentElement) {
        documentScrollTop = document.documentElement.scrollTop;
      }
      scrollTop =bodyScrollTop - documentScrollTop > 0 ? bodyScrollTop : documentScrollTop;
      return scrollTop;
    },
    //下拉触底监听事件处理方法
    scrollHander() {
      if (this.isLoading || this.isDone) return;
      //文本可见高度
      let baseHeight = document.documentElement.clientHeight;
      //可滑动包括溢出隐藏部分
      let moreHeight = document.body.scrollHeight;
      //滑动距离
      let scrollTop = this.getScrollTop();
      //判断是否触底
      if (baseHeight + scrollTop > moreHeight) {
        this.isLoading = true;
        this.onScroll();
      }
    }
  },
  mounted() {
    this.scrollview = window;
    this.scrollview.addEventListener("scroll", this.scrollHander, false);
    this.$nextTick(this.init());
  }
};
</script>

父组件使用scrollLower

<template>
  <div>
    <scrollLower:onScroll="loadingData" ref="scroll">
      <ul slot="list" class="ul">
        <li v-for="item in list" class="listitem">{{item}}</li>
      </ul>
    </scrollLower>
  </div>
</template>

<script>
import scrollLower from "@/components/scrollLower";
export default {
  components: { scrollLower },
  data() {
    return {
      list: [1, 2, 3, 4, 5, 6, 7, 5, 8, 9, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0]
    };
  },
  methods:{
  //当滚动到底部时执行加载数据的函数
      loadingData(){
          setTimeout(()=>{
             this.list.push('d')
              this.$refs.scroll.$emit('loadedDone')
          },2000)
      }
  }
};
</script>
<style>
.listitem{
    width: 500px;
    height: 150px;
    border: 1px solid;
}
</style>

你可能感兴趣的:(vue)