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前端组
      上次更新: 3/17/2020, 8:46:00 PM