基于vue2.0实现仿百度前端分页效果(二)
前言
上篇文章中,已经使用vue实现前端分页效果,这篇文章我们单独将分页抽离出来实现一个分页组件
先看实现效果图

代码实现
按照惯例,我们在冻手实现的时候还是先想一想vue实现组件的思路
1、需要提前设定哪些参数需要暴露出来给父组件传递
<Paging
:name="name"
@change="onPageChange"
:page-size="size"
:total="total"
layout="jumper,total"
:current-page="curPage"
/>
方法及参数说明
属性
page-size 每页显示条目个数
total 总条目数
current-page 当前页数
layout 布局 默认不显示 jumper,total
事件
change 当前页改变时触发
2、再一个就是涉及到的父子组件通信
这里主要通过props向子组件传递参数
在子组件中使用emit自定义事件返回数据给父组件
a.字符串数组形式props
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
或者指定每个prop的值类型
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object
}
b.props验证
props: {
// 基础的类型检查 (`null` 匹配任何类型)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
使用props传递数据给子组件 ,子组件主要有三种形式来接收到父组件传递过来的参数
props字符串数组、指定每个prop值类型以及props验证,通常我们会使用props验证
分析完之后,接下来我们可以冻手实现了
1、这里我们用vue-cli先创建一个vue项目
安装vue-cli
$npm install -g vue-cli
创建vue项目
$vue init webpack my-project
项目运行
$cd my-project
$npm run dev
2、在components文件下创建一个Paging组件
<template>
<div class="paging clearfix">
<div class="page-size fl" v-if="isShowTotal">共{{total}}条</div>
<ul class="page-list fl clearfix">
<li @click="changePage(currentPage-1)">上一页</li>
<li :class="{'active':currentPage==item.val}" v-for="item in pagelist" v-text="item.text" @click="changePage(item.val)">1</li>
<li @click="changePage(currentPage+1)">下一页</li>
</ul>
<div class="page-jump fl" v-if="isShowJumper">
前往<input class="input" type="text" v-model="toPage" @keydown="submit(toPage,$event)">页
<!-- <button @click="changePage(toPage)">确定</button> -->
</div>
</div>
</template>
<script>
export default {
name: 'Paging',
// props:[
// 'name'
// ],
// prop验证
props:{
name:String,
pageSize: {
type: Number,
default: 10
},
total: {
type: Number,
default: 0
},
currentPage: {
type: Number,
default: 1
},
layout:{
type: String
}
},
data () {
return {
isShowJumper:false,
isShowTotal:false,
toPage:'',//跳转到x页
pageGroup:10//可见分页数量 默认10个分页数
}
},
created: function () {
console.log('created');
this.isShowTotal = this.layout.indexOf('total')!==-1;
this.isShowJumper = this.layout.indexOf('jumper')!==-1;
},
mounted: function () {
console.log('mounted',this.layout);
},
computed:{
totalPage:function(){
return Math.ceil(this.total / this.pageSize)
},
pagelist:function(){
var list = [];
var count = Math.floor(this.pageGroup/2), center = this.currentPage;
var left = 1,right = this.totalPage;
if(this.totalPage>this.pageGroup){
if(this.currentPage>count+1){
if(this.currentPage < this.totalPage - count){
left = this.currentPage - count;
right = this.currentPage + count-1;
}else{
left = this.totalPage - this.pageGroup+1;
}
}else{
right = this.pageGroup;
}
}
// 遍历添加到数组里
while(left<=right){
list.push({
text:left,
val:left
});
left++;
}
return list;
}
},
methods:{
// 回车事件
submit(toPage,e){
// console.log('e.keyCode',toPage,e.keyCode)
// key.Code === 13表示回车键
if(e.keyCode === 13){
//逻辑处理
this.changePage(toPage);
}
},
changePage:function(idx){
if(idx!=this.currentPage && idx>0 && idx<=this.totalPage){
// 触发父组件事件 pageChange会转换成小写pagechange
this.$emit('change',{curPage:Number(idx)});
}
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
*{
padding: 0;
margin: 0;
}
.fl{
float: left;
}
.clearfix:after{
display: block;
content: '';
clear: both;
}
.page-size{
height: 26px;
line-height: 26px;
}
.page-list{
}
.page-jump{
height: 26px;
line-height: 26px;
margin-left: 20px;
}
.page-jump .input{
width: 32px;
padding: 4px 2px;
border-radius: 2px;
border: 1px solid #dcdfe6;
margin: 0 4px;
}
ul{
list-style: none;
}
ul li{
float: left;
color: #606266;
background: #f4f4f5;
padding: 2px 8px;
cursor: pointer;
border-radius: 2px;
margin: 0 5px;
}
ul>li.active{
background: #409eff;
color:#fff;
}
</style>
3、在父组件中引入并使用组件
<template>
<div>
<!-- 分页组件 -->
<Paging
:name="name"
@change="onPageChange"
:page-size="size"
:total="total"
layout="jumper,total"
:current-page="curPage"
/>
</div>
</template>
<!--
Paging属性
page-size 每页显示条目个数
total 总条目数
current-page 当前页数
layout 布局 默认不显示 jumper,total
Paging事件
change 当前页改变时触发
-->
<script>
import Paging from '@/components/Paging';
export default {
name: 'Index',
components:{
Paging
},
data () {
return {
msg: 'hello',
name:'阿健a',
size:10,
total:201,
curPage:1
}
},
methods:{
onPageChange:function(page){
this.curPage = page.curPage;
}
}
}
</script>
遇到的问题
1、在子组件中修改currentPage时报错
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders
在使用组件时,传入的prop,被组件内部又做了一次修改
避免直接修改prop,因为当父组件重新呈现时,值将被覆盖
changePage:function(idx){
if(idx!=this.currentPage && idx>0 && idx<=this.totalPage){
this.currentPage = idx;
// 触发父组件事件 pageChange会转换成小写pagechange
this.$emit('change');
}
}
解决
修改代码,通过emit传递curPage给父组件,让父组件修改
changePage:function(idx){
if(idx!=this.currentPage && idx>0 && idx<=this.totalPage){
// 触发父组件事件 pageChange会转换成小写pagechange
this.$emit('change',{curPage:idx});
}
}
父组件监听事件更新curPage
onPageChange:function(page){
this.curPage = page.curPage;
}
最后
以上就是分页组件的整个实现过程 ,其实只要搞清楚父子组件是如何传参的,以及我们实现一个组件需要暴露哪些参数给父组件,整个实现过程还是不难的
基于vue2.0实现仿百度前端分页效果(二)的更多相关文章
- 基于vue2.0实现仿百度前端分页效果(一)
前言 最近在接手一个后台管理项目的时候,由于之前是使用jquery+bootstrap做的,后端使用php yii框架,前后端耦合在一起,所以接手过来之后通过vue进行改造,但依然继续使用的boots ...
- vue2.0+Element UI 表格前端分页和后端分页
之前写过一篇博客,当时对element ui框架还不太了解,分页组件用 html + css 自己写的,比较麻烦,而且只提到了后端分页 (见 https://www.cnblogs.com/zdd20 ...
- 基于vue2.0的分页组件开发
今天安排的任务是写基于vue2.0的分页组件,好吧,我一开始是觉得超级简单的,但是越写越写不出来,写的最后乱七八糟的都不知道下句该写什么了,所以重新捋了思路,小结一下- 首先写组件需要考虑: 要从父组 ...
- 基于vue2.0前端组件库element中 el-form表单 自定义验证填坑
eleme写的基于vue2.0的前端组件库: http://element.eleme.io 我在平时使用过程中,遇到的问题. 自定义表单验证出坑: 1: validate/resetFields 未 ...
- 基于vue2.0的一个豆瓣电影App
1.搭建项目框架 使用vue-cli 没安装的需要先安装 npm intall -g vue-cli 使用vue-cli生成项目框架 vue init webpack-simple vue-movie ...
- vue-swiper 基于Vue2.0开发 轻量、高性能轮播插件
vue-swiper 基于 Vue2.0 开发,基本满足大部分功能 轻量.高性能轮播插件.目前支持 无缝衔接自动轮播.无限轮播.手势轮播 没有引入第三方库,原生 js 封装,打包之后只有 8.2KB ...
- 【饿了么】—— Vue2.0高仿饿了么核心模块&移动端Web App项目爬坑(三)
前言:接着上一篇项目总结,这一篇是学习过程记录的最后一篇,这里会梳理:评论组件.商家组件.优化.打包.相关资料链接.项目github地址:https://github.com/66Web/ljq_el ...
- 基于vue2.0打造移动商城页面实践 vue实现商城购物车功能 基于Vue、Vuex、Vue-router实现的购物商城(原生切换动画)效果
基于vue2.0打造移动商城页面实践 地址:https://www.jianshu.com/p/2129bc4d40e9 vue实现商城购物车功能 地址:http://www.jb51.net/art ...
- 基于vue2.0的在线电影APP,
基于vue2.0构建的在线电影网[film],webpack + vue + vuex + vue-loader + keepAlive + muse-ui + cordova 全家桶,cordova ...
随机推荐
- [SoapUI] 如何同时调用Global Script Library(放在SoapUI安装目录)和项目特有的Script Libary(放在项目代码下)
SoapUI 支持引入多个package: Global Script library : 在SoapUI工具File->Preference中设置Project Script Library: ...
- bittorrent 学习(一) 种子文件分析与bitmap位图
终于抽出时间来进行 BITTORRENT的学习了 BT想必大家都很熟悉了,是一种文件分发协议.每个下载者在下载的同时也在向其他下载者分享文件. 相对于FTP HTTP协议,BT并不是从某一个或者几个指 ...
- 谷歌发布了 T2T(Tensor2Tensor)深度学习开源系统
谷歌开源T2T模型库,深度学习系统进入模块化时代! 谷歌大脑颠覆深度学习混乱现状,要用单一模型学会多项任务 https://github.com/tensorflow/models https://g ...
- js 时间戳转日期
timestampToTime(10位时间戳) function timestampToTime(timestamp) { var date = new Date(timestamp * 1000); ...
- DedeCMS文章页去img图片width和height属性
方法一:正则匹配去除 打开include/ arc.archives.class.php,查找代码: //设置全局环境变量 $this->Fields['typename'] = $this-& ...
- [solution] JZOJ-5781 秘密通道
JZOJ-5781[秘密通道 ]solution 题面 Description 有一副$nm$的地图,有$nm$块地,每块是下列四种中的一种: 墙:用#表示,墙有4个面,分别是前面,后面,左面,右面. ...
- 【UWP】手动实现 WebAuthenticationBroker
在 UWP 中,如果要进行 OAuth 授权,那很大概率是会用上 WebAuthenticationBroker 这个类的,例如微博授权这种. 在一般情况下来说,WebAuthenticationBr ...
- CPP之内存分配
new & delete expression 1. Introduction A new expression allocates and constructs an object of a ...
- Centos 执行top命令详细解读
1.作用:top命令用来显示执行中的程序进程,使用权限是所有用户. 2.格式:top [-] [d delay] [q] [c] [S] [s] [i] [n] 3.主要参数: d:指定更新的间隔,以 ...
- [UWP]如何实现UWP平台最佳图片裁剪控件
前几天我写了一个UWP图片裁剪控件ImageCropper(开源地址),自认为算是现阶段UWP社区里最好用的图片裁剪控件了,今天就来分享下我编码的过程. 为什么又要造轮子 因为开发需要,我们需要使用一 ...