基于Vue的简单通用分页组件
分页组件是每一个系统里必不可少的一个组件,分页组件分为两部分。第一部分是模版部分,用于显示当前分页组件的状态,例如正在获取数据、没有数据、没有下一页等等;第二部分是分页数据对象,用于封装一个分页组件的属性和方法,例如获取数据的 url、当前第几页(page)、每次加载条数(count)、一共有多少页(totalPage)等等,方法可能会有上一页、下一页、处理数据等等。
分页数据对象
import base from '@/api/base'
export default class Pagination {
constructor({ url, processFunc, processExt, count = 10, isMock = false }) {
// 数据访问地址
this.url = url
// 数据集合
this.list = []
// 第几页
this.page = 1
// 一共几页
this.totalPage = 1
// 加载数据条数
this.count = count
// 数据处理函数
this.processFunc = processFunc
// 错误处理函数
this.processExt = processExt
// 正在加载中
this.loading = false
// 参数
this.params = {}
// 是否底部
this.reachBottom = false
// 是否为空
this.empty = true
// 是否需要清除
this.toClear = false
// 是否为mock数据
this.isMock = isMock
}
/**
* 加载下一页数据
*/
async next(args) {
if (this.loading) {
// console.warn('page loading!')
return this
}
const param = {
pageNo: this.page,
pageSize: this.count
}
// 附加参数
this.loading = true
try {
Object.assign(param, args)
let res
let data
try {
res = await base.get(this.url, param)
data = res.data
} catch (e) {
if (typeof this.processExt === 'function') {
data = this.processExt(e)
} else {
throw new Error(e)
}
}
// 底部判断
if (data === null || data.length < 1) {
if (this.toClear) {
this.clear()
} else {
this.reachBottom = true
}
return this
}
this.empty = false
// 处理数据
this._processData(data)
// 设置数据
if (this.toClear) {
this.list = data
this.toClear = false
} else {
this.list = this.list.concat(data)
}
++this.page
this.totalPage = res.page.totalPages
if (
(res.page && res.page.page === res.page.totalPages) ||
data.length < this.count
) {
this.reachBottom = true
}
return this
} finally {
this.loading = false
}
}
/**
* 恢复到第一页
*/
reset() {
this.empty = true
this.toClear = true
this.page = 1
this.reachBottom = false
}
clear() {
this.toClear = false
this.page = 1
this.list = []
}
/**
* 处理数据(私有)
*/
_processData(data) {
if (this.processFunc) {
for (let i in data) {
const result = this.processFunc(data[i])
if (result) {
data[i] = result
}
}
}
}
}
分页模版
<template>
<div class="z-page-stat">
<p v-show="page.loading" class="page-loading">
<span class="ign-loading"></span>
</p>
<div
class="u-more-btn"
v-show="showLoadMore && !page.reachBottom && !page.loading && !page.empty"
@click="$emit('nextPage')"
>
<span>查看更多</span>
</div>
<p class="reach-btm" v-show="showBtmTx && !page.empty && page.reachBottom">
到底了~
</p>
<div class="page-empty" v-show="!page.loading && page.empty">
<div class="empty-inner">
<div class="img-bg" v-if="emptyImg">
<img
v-if="!emptyImg || emptyImg == 1"
src="../../img/empty-page.png"
alt=""
/>
</div>
<p class="tx">{{emptyText}}</p>
<div class="empty-ctn">
<slot name="empty"></slot>
</div>
</div>
</div>
<slot name="other"></slot>
</div>
</template>
<script>
export default {
name: 'pageStatus',
data() {
return {}
},
props: {
page: {},
emptyImg: {},
emptyText: {
type: String,
default: '暂时没有数据'
},
showLoadMore: {
// 是否显示加载更多按钮
type: Boolean,
default: false
},
showBtmTx: {
// 到底了文字要不要显示
type: Boolean,
default: true
}
},
components: {},
created: function() {},
mounted: function() {},
methods: {}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.z-page-stat
text-align center
letter-spacing 2px
color #757575
line-height 60px
.page-loading
.ign-loading
border-radius 100%
margin 16px 0
animation-fill-mode both
border 2px solid #e8473f /* no */
border-bottom-color transparent
height 25px /* no */
width 25px /* no */
background transparent !important
display inline-block
animation rotate 1s 0s linear infinite
.page-empty
position absolute
left 0
width 100%
top 50%
transform translate(0, -50%)
.empty-inner
width 320px
margin 0 auto
.img-bg
position relative
display inline-block
width 254px
height 254px
background #d6d6d6
border-radius 50%
margin-bottom 20px
img
width 94px
margin-top 28px
.tx
color #8c8c8c
.empty-ctn
.u-btn
margin-top 90px
margin-left 20px
border 2px solid #464646 /* no */
box-shadow none
width 168px
height 62px
line-height 62px
</style>
使用组件
<template>
<div>
<div class="card-content" v-for="act in page.list" :key="act.id">
<p>
{{act.title}}
</p>
</div>
<p-status :page="page"></p-status>
</div>
</template>
<script>
import { mainList } from '@/api/activity'
import PageStatus from 'comps/pageStatus.vue'
export default {
data() {
return {
page: mainList()
}
},
mixins: [appPage],
computed: {},
created: async function() {
this.page.next({
/*传参*/
})
},
components: { 'p-status': PageStatus }
}
</script>
// @/api/activity
import Pagination from '@/utils/Pagination'
/**
* 列表
*/
export function mainList() {
const url = `/activity/activity/list.do`
return new Pagination({
url: url
})
}
基于Vue的简单通用分页组件的更多相关文章
- 基于Vue.js的表格分页组件
有一段时间没更新文章了,主要是因为自己一直在忙着学习新的东西而忘记分享了,实在惭愧. 这不,大半夜发文更一篇文章,分享一个自己编写的一个Vue的小组件,名叫BootPage. 不了解Vue.js的童鞋 ...
- Vue.js的表格分页组件
转自:http://www.cnblogs.com/Leo_wl/p/5522299.html 有一段时间没更新文章了,主要是因为自己一直在忙着学习新的东西而忘记分享了,实在惭愧. 这不,大半夜发文更 ...
- 发布自己第一个npm 组件包(基于Vue的文字跑马灯组件)
一.前言 总结下最近工作上在移动端实现的一个跑马灯效果,最终效果如下: 印象中好像HTML标签的'marquee'的直接可以实现这个效果,不过 HTML标准中已经废弃了'marquee'标签 既然HT ...
- ReactJS实现的通用分页组件
大家多少都自己写过各种版本的分页工具条吧,像纯服务版的,纯jsWeb板的,Angular版的,因为这个基础得不能再基础的功能太多地方都会用到,下面我给出以个用ReactJS实现的版本,首先上图看下效果 ...
- vue-awesome-swipe 基于vue使用的轮播组件 使用(改)
npm install vue-awesome-swiper --save //基于vue使用的轮播组件 <template> <swiper :options="swi ...
- 基于Vue开发的tab切换组件
github地址:https://github.com/MengFangui/VueTabSwitch 1.index.html <!DOCTYPE html> <html lang ...
- asp.net MVC通用分页组件 使用方便 通用性强
asp.net MVC通用分页组件 使用方便 通用性强 该分页控件的显示逻辑: 1 当前页面反色突出显示,链接不可点击 2 第一页时首页链接不可点击 3 最后一页时尾页链接不可点击 4 当前页面左 ...
- vue修改elementUI的分页组件视图没更新问题
转: vue修改elementUI的分页组件视图没更新问题 今天遇到一个小问题平时没留意,el-pagination这个分页组件有一个属性是current-page当前页.今天想在methods里面手 ...
- 基于vue2.0的一个分页组件
分页组件在项目中经常要用到之前一直都是在网上找些jq的控件来用(逃..),最近几个项目用上vue了项目又刚好需要一个分页的功能.于是百度发现几篇文章介绍的实在方式有点复杂, 没耐心看自己动手造轮子写了 ...
随机推荐
- React 异步组件
之前写过一篇 Vue 异步组件的文章,最近在做一个简单项目的时候又想用到 React 异步组件,所以简单地了解了一下使用方法,这里做下笔记. 传统的 React 异步组件基本都靠自己实现,自己写一个专 ...
- Windows 7防火墙阻止了远程桌面连接的解决方法
在[系统属性]中已经设置了允许远程桌面连接了,但是还是不能远程桌面的话,很可能是你的windows防火墙处于“启用”状态,防火墙阻止了windows 7系统的远程桌面连接.你可以使用以下的方法检查解决 ...
- Spark系列-核心概念
Spark系列-初体验(数据准备篇) Spark系列-核心概念 一. Spark核心概念 Master,也就是架构图中的Cluster Manager.Spark的Master和Workder节点分别 ...
- 项目--解决MySQL数据库插入中文乱码
转载自:http://blog.csdn.net/zzh920625/article/details/51226312 情景再现] 如图,在项目中使用MySQL数据库,在做插入操作时,写入英文字符没有 ...
- 【转】Android 内核初识(6)SystemServer进程
简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...
- jmeter验证WEB页面的href链接请求
1. 第一步: 创建Samper_HTTP请求,打开测试页面 2. 第二步: 创建后置处理器_正则表达式(也有其他方式,这里仅介绍正则) 如图 3. 第三步 创建逻辑控制器_ForEach控制器,配置 ...
- LeetCode559. Maximum Depth of N-ary Tree
第一次写出了具有迭代和递归的函数,还是有点收获的,虽然题目比较简答 当要对某些对象重复使用时,考虑循环,也就是迭代 当函数可以简化一个重复的操作时,考虑递归,而且就当下一次使用这和函数的结果已经有啦, ...
- P1880 [NOI1995]石子合并
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- The Ribbon Tab with id: "Ribbon.Read" has not been made available for this page or does not exist.
The Ribbon Tab with id: "Ribbon.Read" has not been made available for this page or does no ...
- UOJ#34. 多项式乘法(NTT)
这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+1 个整数,表示第一个多项式的 00 到 nn 次项 ...