基于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 ...
随机推荐
- java多线程系列8 高级同步工具(2)CountDownLatch
CountDownLatch,计数器的初始值为线程的数量.每当一个线程完成了自己的任务后, 计数器的值就会减1.当计数器值到达0时,它表示所有的线程已经完成了任务, 然后在闭锁上等待的线程就可以恢复执 ...
- python中使用OpenCV处理图片
1.导入OpenCV包 import cv2 2.读取图片 cv2.imread(image_path, mode) 读入函数,包含两个参数,第一个为图片路径及图片名,第二个为读取图片方 ...
- Java 8 Lambda 表达式及 Stream 在集合中的用法
简介 虽然 Java 8 已经发布有一段时间了,但是关于 Java 8 中的 Lambda 表达式最近才开始系统的学习,刚开始就被 Stream 的各种骚操作深深的吸引住了,简直漂亮的不像 Java. ...
- CentOs7安装PHP
来源:https://jingyan.baidu.com/article/2d5afd692df18d85a3e28e4c.html 一.下载源码 1.cd /usr/local/src/ 2. 执行 ...
- ABP框架系列之八:(Introduction-介绍)
Introduction We are creating different applications based on different needs. But implementing commo ...
- js-实时获取键值码
<script> document.onkeydown=function(event){ console.log(event.keyCode) //在控制台打印 } </scr ...
- Celery分布式任务队列快速入门
本节内容 1. Celery介绍和基本使用 2. 项目中使用Celery 3. Celery定时任务 4. Celery与Django结合 5. Django中使用计划任务 一 Celery介绍和基 ...
- 分享Pos函数(比FastPos还要快)
): Integer; ): Integer; 主要用途是搜索字符串中第n个Substr. 经过测试,这2个函数的速度比直接用Pos+Copy快好几倍(如果字符串够长,可能10几倍) 比Pos+Del ...
- 背水一战 Windows 10 (71) - 控件(控件基类): UIElement - RenderTransform(2D变换), Clip(剪裁)
[源码下载] 背水一战 Windows 10 (71) - 控件(控件基类): UIElement - RenderTransform(2D变换), Clip(剪裁) 作者:webabcd 介绍背水一 ...
- vue中的双向绑定
概述 今天对双向绑定感兴趣了,于是去查了下相关文章,发现有用脏检查的(angular.js),有用发布者-订阅者模式的(JQuery),也有用Object.defineProperty的(vue),其 ...