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 相关文章推荐
JS中简单的实现像C#中using功能(有源码下载)
Jan 09 Javascript
javascript 程序库的比较(一)之DOM功能
Apr 07 Javascript
jquery实现简单的拖拽效果实例兼容所有主流浏览器(优化篇)
Jun 28 Javascript
IE6已终止操作问题的2种情况及解决
Apr 23 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)
Dec 10 Javascript
jQuery prototype冲突的2种解决方法(附demo示例下载)
Jan 21 Javascript
JQuery核心函数是什么及使用方法介绍
May 03 Javascript
Js操作DOM元素及获取浏览器高宽的简单方法
Sep 08 Javascript
vue2.0全局组件之pdf详解
Jun 26 Javascript
理顺8个版本vue的区别(小结)
Sep 17 Javascript
JS尾递归的实现方法及代码优化技巧
Jan 19 Javascript
JavaScript高阶教程之“==”隐藏下的类型转换
Apr 11 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
ie6 动态缩略图不显示的原因
2009/06/21 PHP
PHP开发中的错误收集,不定期更新。
2011/02/03 PHP
163的邮件用phpmailer发送(实例详解)
2013/06/24 PHP
php使用Header函数,PHP_AUTH_PW和PHP_AUTH_USER做用户验证
2016/05/04 PHP
php+mysql实现的二级联动菜单效果详解
2016/05/10 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
JavaScript Cookie的读取和写入函数
2009/12/08 Javascript
js函数的延迟加载实现代码
2012/10/11 Javascript
jQuery中的height innerHeight outerHeight区别示例介绍
2014/06/15 Javascript
jQuery选择器querySelector的使用指南
2015/01/23 Javascript
深入理解JavaScript系列(28):设计模式之工厂模式详解
2015/03/03 Javascript
javascript实现 百度翻译 可折叠的分享按钮列表
2015/03/12 Javascript
JavaScript动态改变表格单元格内容的方法
2015/03/30 Javascript
nodejs调用cmd命令实现复制目录
2015/05/04 NodeJs
不想让浏览器运行javascript脚本的方法
2015/11/20 Javascript
vue2 router 动态传参,多个参数的实例
2017/11/10 Javascript
webpack 插件html-webpack-plugin的具体使用
2018/04/09 Javascript
JS中实现一个下载进度条及播放进度条的代码
2019/06/10 Javascript
Vue中util的工具函数实例详解
2019/07/08 Javascript
jQuery操作选中select下拉框的值代码实例
2020/02/07 jQuery
webpack中的模式(mode)使用详解
2020/02/20 Javascript
Python中字符串对齐方法介绍
2015/05/21 Python
python实现比较两段文本不同之处的方法
2015/05/30 Python
Python中使用支持向量机SVM实践
2017/12/27 Python
简单了解python的break、continue、pass
2019/07/08 Python
HTML5自定义data-* data(obj)属性和jquery的data()方法的使用
2012/12/13 HTML / CSS
HTML5 video标签(播放器)学习笔记(一):使用入门
2015/04/24 HTML / CSS
Spartoo西班牙官网:法国时尚购物网站
2018/03/27 全球购物
铭万公司.net面试题笔试题
2014/07/20 面试题
金融专业毕业生推荐信
2013/11/26 职场文书
人大调研汇报材料
2014/08/14 职场文书
学习优秀党员杨宗兴先进事迹材料思想汇报
2014/09/14 职场文书
高中生学习计划书
2014/09/15 职场文书
党支部2014年度工作总结
2014/12/04 职场文书
银行求职信范文怎么写
2015/03/20 职场文书
导游经典开场白——导游词
2019/04/17 职场文书