vue-infinite-loading2.0 中文文档详解


Posted in Javascript onApril 08, 2018

简介

这是一个使用在Vue.js中的无限滚动插件,它可以帮助你快速创建一个无限滚动列表。

特点

  1. 移动端支持友好
  2. 兼容任何一个可以滚动的元素
  3. 有不同的旋转器可以作为加载动画
  4. 支持加载后显示结果
  5. 支持两个方向的无限加载

<p id="installation">安装</p>

<strong>注意:vue-infinite-loading2.0只能在Vue.js2.0中使用。如果你想在Vue.js1.0中使用,请安装vue-infinite-loading1.3版本</strong>

npm install vue-infinite-loading --save

导入方式

es6模块导入方式

import InfiniteLoading from 'vue-infinite-loading';
export default {
 components: {
  InfiniteLoading,
 },
};

CommonJS 模块导入方式

const InfiniteLoading = require('vue-infinite-loading');
export default {
 components: {
   InfiniteLoading,
 },
};

其他方式

<script src="/path/to/vue-infinite-loading/dist/vue-infinite-loading.js"></script>

vue-infinite-loading.js会注册一个全局变量VueInfiniteLoading,使用时需要这样:

...
 components: {
   VueInfiniteLoading:VueInfiniteLoading.default,
 }
...

开始

基础使用

在本例中,我们将创建一个基本的无限列表,有如下三个步骤:

  1. 在你的模板中,用v-for创建一个列表
  2. 将InfiniteLoading组件放在列表的底部;
  3. 将InfiniteLoading组件的ref属性设置为infiniteLoading,因为要用它来触发事件。
  4. 为InfiniteLoading组件创建并绑定一个加载回调函数。

Template

<template>
 <div>
  <p v-for="item in list">
  Line:
  <span v-text="item"></span>
  </p>
  <infinite-loading :on-infinite="onInfinite" ref="infiniteLoading">  </infinite-loading>
 </div>
</template>

Script

import InfiniteLoading from 'vue-infinite-loading';
export default {
 data() {
  return {
   list: []
  };
 },
 methods: {
  onInfinite() {
   setTimeout(() => {
    const temp = [];
    for (let i = this.list.length + 1; i <= this.list.length + 20; i++) {
     temp.push(i);
    }
    this.list = this.list.concat(temp);
    this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
   }, 1000);
  }
 },
 components: {
  InfiniteLoading
 }
};

在<strong>onInfinite</strong>函数中,每次我们都push 20 个数字到list数组中。我们使用<strong>setTimeout</strong>来模拟异步请求。最后,不要忘了触发一个<strong>$InfiniteLoading:loaded</strong>事件,它将告诉<strong>InfiniteLoading</strong>组件,数据已经下载成功。

现在,我们可以根据上面的代码,来显示效果。

<p id="hacker">例子:黑客新闻列表页面</p>

在这个例子中,我们将模仿一个黑客新闻列表页面,但是会用<strong>InfiniteLoading</strong>代替<strong>分页</strong>

在开始这个例子之前,我们需要准备以下内容:

  1. 获取新闻列表的API,在本例中我们使用 HN Search API
  2. 导入axios插件来请求数据

Template

<div class="hacker-news-list">
 <div class="hacker-news-header">
  <a target="_blank" href="http://www.ycombinator.com/" rel="external nofollow" rel="external nofollow" >
   ![](https://news.ycombinator.com/y18.gif)
  </a>
  <span>Hacker News</span>
</div>
<div class="hacker-news-item" v-for="(item, key) in list">
 <span class="num" v-text="key + 1"></span>
 <p>
  <a target="_blank" :href="item.url" rel="external nofollow" rel="external nofollow" v-text="item.title"></a>
 </p>
 <p>
  <small>
   <span v-text="item.points"></span>
   points by
   <a target="_blank" :href="'https://news.ycombinator.com/user?id=' + item.author" rel="external nofollow" rel="external nofollow" 
    v-text="item.author"></a>
    |
   <a target="_blank" :href="'https://news.ycombinator.com/item?id=' + item.objectID" rel="external nofollow" rel="external nofollow" 
    v-text="item.num_comments + ' comments'"></a>
  </small>
 </p>
</div>
 <infinite-loading :on-infinite="onInfinite" ref="infiniteLoading">
 <span slot="no-more">
  There is no more Hacker News :(
 </span>
 </infinite-loading>
</div>

在模板中,我们为黑客新闻列表创建了一个header 和 一个list 。在这个例子中的<strong>InfiniteLoading</strong>组件,与上个例子中使用方式有些不同。我们基于<strong>slot</strong>自定义了当没有更多数据时的提示内容。

Script

import InfiniteLoading from 'vue-infinite-loading';
import axios from 'axios';
const api = 'http://hn.algolia.com/api/v1/search_by_date?tags=story';
export default {
 data() {
  return {
   list: []
  };
 },
 methods: {
  onInfinite() {
   axios.get(api, {
    params: {
     page: this.list.length / 20 + 1
    }
   }).then((res) => {
    if (res.data.hits.length) {
     this.list = this.list.concat(res.data.hits);
     this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
     if (this.list.length / 20 === 3) {
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
     }
    } else {
     this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
    }
   });
  }
 },
 components: {
  InfiniteLoading
 }
};

在<strong>onInfinite</strong>函数中,我们请求了一页的新闻,并且每次将它们推入到list数组中。如果我们请求了3页新闻,将触发 <strong>$InfiniteLoading:complete</strong>事件去告诉<strong>InfiniteLoading</strong>组件,现在已经没有更多数据可以加载了。它将显示我们自定义在模板中的,表示没有更多数据的提示内容。

Style

.hacker-news-list .hacker-news-item {
  margin: 10px 0;
  padding: 0 10px 0 32px;
  line-height: 16px;
  font-size: 14px;
}
.hacker-news-list .hacker-news-item .num {
 margin-top: 1px;
 margin-left: -32px;
 float: left;
 width: 32px;
 color: #888;
 text-align: right;
}
.hacker-news-list .hacker-news-item p {
 padding-left: 8px;
 margin: 0;
}
.hacker-news-list .hacker-news-item .num:after {
 content: ".";
}
.hacker-news-list .hacker-news-item p>a {
 color: #333;
 padding-right: 5px;
}
.hacker-news-list .hacker-news-item p a {
 text-decoration: none;
}
.hacker-news-list .hacker-news-item p small, .hacker-news-list .hacker-news-item p small a {
 color: #888;
}

<p id="use">与过滤器一块使用</p>

在上个例子的基础上,我们将在头部创建一个下拉选择作为过滤器,当我们改变过滤器,列表将会重新加载。

Template

<div class="hacker-news-list">
<div class="hacker-news-header">
 <a target="_blank" href="http://www.ycombinator.com/" rel="external nofollow" rel="external nofollow" >
  ![](https://news.ycombinator.com/y18.gif)
 </a>
 <span>Hacker News</span>
 <select v-model="tag" @change="changeFilter()">
  <option value="story">Story</option>
  <option value="poll">Poll</option>
  <option value="show_hn">Show hn</option>
  <option value="ask_hn">Ask hn</option>
  <option value="front_page">Front page</option>
 </select>
</div>
<div class="hacker-news-item" v-for="(item, key) in list">
 <span class="num" v-text="key + 1"></span>
 <p>
  <a target="_blank" :href="item.url" rel="external nofollow" rel="external nofollow" v-text="item.title"></a>
 </p>
 <p>
  <small>
   <span v-text="item.points"></span>
   points by
   <a target="_blank" :href="'https://news.ycombinator.com/user?id=' + item.author" rel="external nofollow" rel="external nofollow" 
     v-text="item.author"></a>
   |
   <a target="_blank" :href="'https://news.ycombinator.com/item?id=' + item.objectID" rel="external nofollow" rel="external nofollow" 
     v-text="item.num_comments + ' comments'"></a>
  </small>
 </p>
</div>
<infinite-loading :on-infinite="onInfinite" ref="infiniteLoading">
 <span slot="no-more">
  There is no more Hacker News :(
 </span>
</infinite-loading>
</div>

Script

import InfiniteLoading from 'vue-infinite-loading';
import axios from 'axios';
const api = 'http://hn.algolia.com/api/v1/search_by_date';
export default {
 data() {
  return {
   list: [],
   tag: 'story'
  };
 },
 methods: {
  onInfinite() {
   axios.get(api, {
    params: {
     tags: this.tag,
     page: this.list.length / 20 + 1
    }
   }).then((res) => {
    if (res.data.hits.length) {
     this.list = this.list.concat(res.data.hits);
     this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
     if (this.list.length / 20 === 10) {
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
     }
    } else {
     this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
    }
   });
  },
  changeFilter() {
   this.list = [];
   this.$nextTick(() => {
    this.$refs.infiniteLoading.$emit('$InfiniteLoading:reset');
   });
  }
 },
 components: {
  InfiniteLoading
 }
};

在<strong>changeFilter</strong>函数中,我们清楚了列表并等待DOM更新,然后我们触发一个<strong>$InfiniteLoading:reset</strong>事件,目的是让<strong> InfiniteLoading </strong>组件回到最初状态,它将立刻请求新的数据。

Style

在上个例子基础上增加样式

.demo-inner {
 margin-left: 20px;
 width: 261px;
 height: 455px;
 border: 1px solid #ccc;
 overflow: auto;
}
.hacker-news-list .hacker-news-header {
  padding: 2px;
  line-height: 14px;
  background-color: #f60;
}
.hacker-news-list {
 min-height: 455px;
 background-color: #f6f6ef;
}
.hacker-news-list .hacker-news-header select {
  float: right;
  color: #fff;
  background-color: transparent;
  border: 1px solid #fff;
  outline: none;
}

<p id="server">服务端渲染</p>

服务端渲染(SSR)是<strong>Vue.js2.0</strong>的新特性,当你在你的SSR应用中使用这个组件,会得到类似这样的错误:

Error: window is not defined
ReferenceError: window is not defined
  at ...
  at ...
  at e.exports (...)
  at Object. (...)
  at p (...)
  at Object.e.exports.render.e (...)
  at p (...)
  at Object. (...)
  at p (...)
  at e.__esModule.default (...)

因为<strong>style-loader</strong>不支持在这个时候本地导出,详情点这里,所以我们需要下面的变通方案,为了你的SSR应用:

import InfiniteLoading from 'vue-infinite-loading/src/components/Infiniteloading.vue';

代替

import InfiniteLoading from 'vue-infinite-loading';

<strong>npm install less less-loader --save-dev</strong> 如果你还没有安装它们。

然后你的SSR应用应该运行良好。如果不是,你可以加入这个issue去讨论。

<p id="properties">属性<p>

on-infinite

这是一个回调函数,当滚动到距离滚动父元素底部特定距离的时候,会被调用。

通常,在数据加载完成后,你应该在这个函数中发送<strong>$InfiniteLoading:loaded</strong>事件。

- type      Function
- reuqired    true

distance

这是滚动的临界值。如果到滚动父元素的底部距离小于这个值,那么<strong>on-infinite</strong>回调函数就会被调用。

- type     Number
- required   false
- default   100
- unit     pixel

spinner

通过这个属性,你可以选择一个你最喜爱旋转器作为加载动画。点击这里可以看到所有可用的旋转器。

- type     String
- required   false
- default   'default'

ref

正如你所知,这个属性是一个Vue.js的官方指令,用来获取子组件的实例。我们需要用它来得到<strong> InfiniteLoading </strong>组件的实例来发送事件。你可以用这种方式来得到实例:<strong>this.$refs[the value of ref attribute].</strong>

- type   String
- required   true

direction

如果你设置这个属性为top,那么这个组件将在你滚到顶部的时候,调用on-infinite函数。

<strong>警告:你必须在数据加载后,手动地将滚动父元素的scrollTop设置为正确的值,否则,该组件会一次又一次调用on-infinite函数。</strong>

- type     String
- default   'bottom'

<p id="event">事件</p>

<strong>InfiniteLoading </strong>组件将处理一下事件。如果你需要通过组件的实例来<strong>$emit</strong>,则可以通过<strong>ref</strong>属性来得到组件实例。

$InfiniteLoading:loaded

通常,你需要在数据加载后发送这个事件,<strong> InfiniteLoading</strong>组件将隐藏加载动画,并且准备下一次触发。

$InfiniteLoading:complete

如果<strong>InfiniteLoading</strong>组件就不会接收<strong>$InfiniteLoading:loaded</strong>,当你发送这个事件后,它将为用户显示一个没有结果的提示。如果<strong>InfiniteLoading</strong>组件接收过<strong>$InfiniteLoading:loaded</strong>,当你发送这个事件的时候,它会为用户显示一个没有更多内容的提示。你可以利用slot来自定义需要显示的内容。

你的<strong>onInfinite</strong>函数可能像这个样子:

onInfinite() {
  this.$http.get(url, (res) => {
  if (res.data) {
   this.list = this.list.concat(res.data);
   this.$refs[your ref attirbute's value].$emit('$InfiniteLoading:loaded');
  } else {
   this.$refs[your ref attirbute's value].$emit('$InfiniteLoading:complete');
  }
 });
}

$InfiniteLoading:reset

<strong>InfiniteLoading</strong>组件将会回到最初的状态,并且<strong>on-infinite</strong>函数将会立刻被调用。大部分情况下,如果你把这个组件同过滤器或制表符一起使用,这个事件还是有用的。

<p id="slots">插槽</p>

你可以利用<strong>slot</strong>自定义提示的内容,当然,如果你喜欢的话,也可以使用默认内容:

<span slot="{{ slot name }}">
  {{ Your content }}
 </span>

no-results

当<strong>InfiniteLoading</strong>组件接收到<strong>$InfiniteLoading:complete </strong>事件并且它没有接收过<strong>$InfiniteLoading:loaded</strong>事件时,这个内容会显示出来。

- type    String
- default   No results :(

no-more

当<strong>InfiniteLoading</strong>组件接收到<strong>$InfiniteLoading:complete </strong>事件并且它已经接收过<strong>$InfiniteLoading:loaded</strong>事件时,这个内容会出现。

spinner

如果,你不喜欢当前旋转器,你可以自定义自己的旋转器作为加载时的动画。

- type     HTML
- default   default spinner

<p id="spinners">旋转器</p>

你可以用<strong>spinner</strong>属性,选择你最喜爱的旋转器作为加载动画:

<infinite-loading spinner="{{ spinner name }}"></infinite-loading>

点击这里可以查看几个可用的旋转器。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用htc组件制作windows选项卡
Jan 13 Javascript
javascript高亮效果的二种实现方法
Sep 14 Javascript
JavaScript 数组循环引起的思考
Jan 01 Javascript
javascript中[]和{}对象使用介绍
Mar 20 Javascript
JS设置下拉列表框当前所选值的方法
Dec 22 Javascript
javascript实现tab响应式切换特效
Jan 29 Javascript
jQuery解析XML 详解及方法总结
Sep 28 Javascript
微信小程序 wxapp视图容器 view详解
Oct 31 Javascript
js判断数组是否包含某个字符串变量的实例
Nov 24 Javascript
详解.vue文件中style标签的几个标识符
Jul 17 Javascript
Quasar Input:type=&quot;number&quot; 去掉上下小箭头 实现加减按钮样式功能
Apr 09 Javascript
vue中可编辑树状表格的实现代码
Oct 31 Javascript
Vue 页面切换效果之 BubbleTransition(推荐)
Apr 08 #Javascript
JS简单实现查看文档创建日期、修改日期和文档大小的方法示例
Apr 08 #Javascript
Js面试算法详解
Apr 08 #Javascript
JS简单获取并修改input文本框内容的方法示例
Apr 08 #Javascript
详解vue表单——小白速看
Apr 08 #Javascript
JS简单实现动态添加HTML标记的方法示例
Apr 08 #Javascript
React Router v4 入坑指南(小结)
Apr 08 #Javascript
You might like
php 将bmp图片转为jpg等其他任意格式的图片
2009/06/29 PHP
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
php session_start()出错原因分析及解决方法
2013/10/28 PHP
PHP关于htmlspecialchars、strip_tags、addslashes的解释
2014/07/04 PHP
php中单个数据库字段多列显示(单字段分页、横向输出)
2014/07/28 PHP
PHP模板引擎Smarty内置变量调解器用法详解
2016/04/11 PHP
Javascript 验证上传图片大小[客户端]
2009/08/01 Javascript
javascript 面向对象编程 聊聊对象的事
2009/09/17 Javascript
JavaScript 学习笔记(九)call和apply方法
2010/01/11 Javascript
使用按钮控制以何种方式打开新窗口的属性介绍
2012/12/17 Javascript
多个js与css文件的合并方法详细说明
2012/12/26 Javascript
jquery焦点图片切换(数字标注/手动/自动播放/横向滚动)
2013/01/24 Javascript
Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
2013/11/14 Javascript
jQuery实现手机号码输入提示功能实例
2015/04/30 Javascript
jquery如何获取元素的滚动条高度等实现代码
2015/10/19 Javascript
详解JavaScript中基于原型prototype的继承特性
2016/05/05 Javascript
浅谈JQ中mouseover和mouseenter的区别
2016/09/13 Javascript
AngularJS中isolate scope的用法分析
2016/11/22 Javascript
jQuery实现页面顶部下拉广告
2016/12/30 Javascript
JS 在数组指定位置插入/删除数据的方法
2017/01/12 Javascript
Vue数据双向绑定原理及简单实现方法
2018/05/18 Javascript
koa大型web项目中使用路由装饰器的方法示例
2019/04/02 Javascript
python映射列表实例分析
2015/01/26 Python
python pygame模块编写飞机大战
2018/11/20 Python
python做接口测试的必要性
2019/11/20 Python
python多进程并发demo实例解析
2019/12/13 Python
python 8种必备的gui库
2020/08/27 Python
Django日志及中间件模块应用案例
2020/09/10 Python
HTML5 标准将把互联网视频扔回到黑暗时代
2010/02/10 HTML / CSS
html5 worker 实例(二) 图片变换效果
2013/06/24 HTML / CSS
甜品蛋糕店创业计划书范文
2014/02/06 职场文书
大三学生做职业规划:给未来找个方向
2014/02/24 职场文书
供电工程专业求职信
2014/08/09 职场文书
科级干部群众路线教育实践活动对照检查材料思想汇报
2014/09/20 职场文书
2015大学生党员自我评价范文
2015/03/03 职场文书
Java新手教程之ArrayList的基本使用
2021/06/20 Java/Android