Infinite-scroll 无限滚动
代码演示
基础用法
添加 v-infinite-scroll,实现滚动到底部时自动加载。
查看代码 < />
<template>
  <section class="infinite-scroll-demo">
      <ul class="infinite-list"
          v-infinite-scroll="load"
          style="overflow:auto">
        <li v-for="i in count"
            class="infinite-list-item">{{ i }}</li>
      </ul>
  </section>
</template>
<script>
export default {
  data() {
    return {
      count: 0,
    }
  },
  methods: {
    load() {
      this.count += 2
    }
  }
}
</script>
<style lang="scss">
.infinite-scroll-demo {
  .infinite-list {
    height: 200px;
    padding: 0;
    margin: 0;
    list-style: none;
    li {
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 10px;
      height: 40px;
      background: #cfe0ff;
      color: #000622;
      font-size: 14px;
    }
  }
}
</style>在 w-select 中使用
查看代码 < />
<template>
  <section class="infinite-scroll-demo">
      <w-select v-model="value" placeholder="请选择" v-infinite-scroll="loadMore"
                infinite-scroll-disabled="busy"
                infinite-scroll-distance="30"
                infinite-scroll-element="w-select-dropdown__wrap">
        <w-option
          v-for="item in options"
          :key="item.index"
          :label="item.index"
          :value="item.value">
        </w-option>
      </w-select>
  </section>
</template>
<script>
export default {
  data() {
    return {
      options: [],
      value: '',
      // 总页数
      totalPage: 4,
      // 分页数据
      pageNo: 1,
      busy: true
    }
  },
  computed: {
  },
  created() {
    this.$nextTick(() => {
      this.fetchList();
    });
  },
  methods: {
    loadMore() {
      this.busy = true  // 将无限滚动给禁用
      setTimeout(() => {  // 发送请求有时间间隔第一个滚动时间结束后才发送第二个请求
        this.pageNo++;  // 滚动之后加载第二页
        this.fetchList(true);
      }, 300);
    },
    fetchList(flag = false) {
      let resultData = []; // 接口请求的数据
      if (flag) { // 如果flag为true则表示分页
        if (this.pageNo > this.totalPage) {
          // 已经加载到最后一页
          resultData.length = 0;
        } else {
          resultData = [{
            value: '选项1',
            index: this.options.length
          }];
        }
        // 数据拼接
        this.options = this.options.concat(resultData);
        // 接口数据返回空
        this.busy = resultData.length === 0;
      } else {
        // 第一次进入页面
        resultData = [{
          value: '选项1',
          index: 0,
        }, {
          value: '选项2',
          index: 1,
        }, {
          value: '选项3',
          index: 2,
        }, {
          value: '选项4',
          index: 3,
        }, {
          value: '选项5',
          index: 4,
        }, {
          value: '选项4',
          index: 5,
        }, {
          value: '选项5',
          index: 6,
        }, {
          value: '选项4',
          index: 7,
        }, {
          value: '选项5',
          index: 8,
        }];
        this.options = resultData;
        this.busy = false;
      }
    },
  }
}
</script>
<style scoped lang="scss">
</style>
        正在加载中...
      
分页滚动加载
查看代码 < />
<template>
  <section class="infinite-scroll-demo">
      <div style="overflow: auto; height: 200px;">
        <ul class="list clearfix">
          <template v-for="(item, index) in list">
            <li class="list-item"
                :key="index">{{ item.value }}</li>
          </template>
        </ul>
        <!--v-infinite-scroll-->
        <div v-infinite-scroll="loadMore"
              infinite-scroll-disabled="busy"
              infinite-scroll-distance="30"
              class="infinite-scroll-wrapper clearfix">
          {{isComplete ? '我是有底线的' : '正在加载中...'}}
        </div>
      </div>
  </section>
</template>
<script>
export default {
  data() {
    return {
      list: [],
      // 总页数
      totalPage: 4,
      // 分页数据
      pageNo: 1,
      pageSize: 5,
      busy: true,
      // 是否加载到最后一页
      isComplete: false,
    }
  },
  computed: {
  },
  created() {
    this.$nextTick(() => {
      this.fetchList();
    });
  },
  methods: {
    loadMore() {
      this.busy = true  // 将无限滚动给禁用
      setTimeout(() => {  // 发送请求有时间间隔第一个滚动时间结束后才发送第二个请求
        this.pageNo++;  // 滚动之后加载第二页
        this.fetchList(true);
      }, 500);
    },
    fetchList(flag = false) {
      let resultData = []; // 接口请求的数据
      if (flag) { // 如果flag为true则表示分页
        if (this.pageNo > this.totalPage) {
          // 已经加载到最后一页
          resultData.length = 0;
          this.isComplete = true;
        } else {
          resultData = [{
            value: this.list.length + 1,
            index: this.list.length,
          }];
          this.isComplete = false;
        }
        // 数据拼接
        this.list = this.list.concat(resultData);
        // 接口数据返回空
        this.busy = resultData.length === 0;
      } else {
        // 第一次进入页面
        resultData = [{
          value: 1,
          index: 0,
        }, {
          value: 2,
          index: 1,
        }, {
          value: 3,
          index: 2,
        }, {
          value: 4,
          index: 3,
        }, {
          value: 5,
          index: 4,
        }];
        this.list = resultData;
        this.busy = false;
      }
    },
  }
}
</script>
<style scoped lang="scss">
.infinite-scroll-demo {
  .infinite-scroll-wrapper {
    height: 30px;
    line-height: 30px;
    text-align: center;
    color: #000622;
    font-size: 14px;
  }
  .list {
    padding: 0;
    margin: 0;
    list-style: none;
    li {
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 10px;
      height: 40px;
      background: #cfe0ff;
      color: #000622;
      font-size: 14px;
    }
  }
  .clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
  }
  .clearfix {
    *zoom: 1;
  }
}
</style>- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 
可加载到底
查看代码 < />
<template>
  <section class="infinite-scroll-demo">
      <div class="infinite-list-wrapper"
            style="overflow:auto">
        <ul class="list"
            v-infinite-scroll="handleLoading"
            infinite-scroll-disabled="disabled">
          <template v-for="(i, index) in count">
            <li class="list-item"
                :key="index">{{ i }}</li>
          </template>
        </ul>
        <p v-if="isloading">正在加载中...</p>
        <p v-if="isComplete">我是有底线的</p>
      </div>
  </section>
</template>
<script>
export default {
  data() {
    return {
      count: 8,
      isloading: false,
    }
  },
  computed: {
    isComplete() {
      return this.count >= 12
    },
    disabled() {
      return this.isloading || this.isComplete
    }
  },
  methods: {
    handleLoading() {
      this.isloading = true
      setTimeout(() => {
        this.count += 2
        this.isloading = false
      }, 2000)
    },
  }
}
</script>
<style scoped lang="scss">
.infinite-scroll-demo {
  .infinite-list-wrapper {
    height: 200px;
    text-align: center;
    .list {
      padding: 0;
      margin: 0;
      list-style: none;
      li {
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 10px;
        height: 40px;
        background: #cfe0ff;
        color: #000622;
        font-size: 14px;
      }
    }
    p {
      font-size: 14px;
      color: #5e6d82;
      line-height: 1.5em;
    }
  }
}
</style>Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 
|---|---|---|---|---|
| infinite-scroll-element | 当滚动区域不是当前DOM,可自定义当前DOM下的滚动区class选择器 | string | - | - | 
| infinite-scroll-disabled | 是否禁用 | boolean | - | false | 
| infinite-scroll-delay | 节流时延,单位为ms | number | - | 200 | 
| infinite-scroll-distance | 触发加载的距离阈值,单位为px | number | - | 0 | 
| infinite-scroll-immediate | 是否立即执行加载方法,以防初始状态下内容无法撑满容器。 | boolean | - | true | 
贡献者
| 类型 | 参与者 | 
|---|---|
| 设计者 | UED视觉组 | 
| 维护者 | UED前端组 |