基于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 ...
随机推荐
- Android app中存储文件的路径
// 获得缓存文件路径,磁盘空间不足或清除缓存时数据会被删掉,一般存放一些临时文件 // /data/data/<application package>/cache目录 File cac ...
- mySQL配置文件、备份与恢复
mysql配置文件 mysql的配置文件为/etc/my.cnf 配置文件查找次序:若在多个配置文件中均有设定,则最后找到的最终生效 /etc/my.cnf --> /etc/mysql/my. ...
- 深入理解linux关闭文件和删除文件
背景介绍 最近看了linux系统编程(linux system programming)一书,结合深入理解linux内核(understanding the linux kernel)一书,深入理解了 ...
- 17.异常(三)之 e.printStackTrace()介绍
一.关于printStackTrace()方法 public void printStackTrace()方法将此throwable对象的堆栈追踪输出至标准错误输出流,作为System.err的值.输 ...
- Winform嵌入CEF(非正常用法)
(一)复制下面必备文件|-- locales|--en-US.pak|--cef.pak|--cef_100_percent.pak |--cef_200_percent.pak|--cef_exte ...
- uniGUI中Cookies使用中文汉字的方法(使用EncodeString函数编码)
uniGUI中Cookies使用中文汉字的方法(使用EncodeString函数编码) 在目前的UniGUI(ver:0.88)中使用UniApplication.Cookies.SetCooki ...
- MyBatis 源码分析 - SQL 的执行过程
* 本文速览 本篇文章较为详细的介绍了 MyBatis 执行 SQL 的过程.该过程本身比较复杂,牵涉到的技术点比较多.包括但不限于 Mapper 接口代理类的生成.接口方法的解析.SQL 语句的解析 ...
- vue高级组件之provide / inject
转载:https://blog.csdn.net/Garrettzxd/article/details/81407199 在vue中不同组件通信方式如下 1.父子组件,通过prop 2.非父子组件,通 ...
- 关于height、offsetheight、clientheight、scrollheight、innerheight、outerheight的区别一览
平时,不管在pc端页面还是移动端页面,因为我们一般很少会设置某个块的的高度,但是呢,我有时候有需要取到这些高度以便于我们方便进行判断和下一步的编写.一般这个时候我都是直接的获取一个块的高度.heigh ...
- Java学习笔记43(打印流、IO流工具类简单介绍)
打印流: 有两个类:PrintStream,PrintWriter类,两个类的方法一致,区别在于构造器 PrintStream:构造方法:接收File类型,接收字符串文件名,接收字节输出流(Outpu ...