基于vue2.0实现仿百度前端分页效果附实现代码


Posted in Javascript onOctober 30, 2018

前言

上篇文章中,已经使用vue实现前端分页效果,这篇文章我们单独将分页抽离出来实现一个分页组件

先看实现效果图

基于vue2.0实现仿百度前端分页效果附实现代码

代码实现

按照惯例,我们在冻手实现的时候还是先想一想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实现仿百度前端分页效果附实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript 无符号右移运算符
Apr 17 Javascript
js+css在交互上的应用
Jul 18 Javascript
js的onload事件及初始化按钮事件示例代码
Sep 25 Javascript
js动态调用css属性的小规律及实例说明
Dec 28 Javascript
javascript针对cookie的基本操作实例详解
Nov 30 Javascript
AngularJS基础 ng-paste 指令简单示例
Aug 02 Javascript
老生常谈jquery id选择器和class选择器的区别
Feb 12 Javascript
vue项目常用组件和框架结构介绍
Dec 24 Javascript
js中el表达式的使用和非空判断方法
Mar 28 Javascript
JS回调函数简单易懂的入门实例分析
Sep 29 Javascript
用js实现放大镜效果
Oct 28 Javascript
vue中data里面的数据相互使用方式
Jun 05 Vue.js
小程序实现多选框功能
Oct 30 #Javascript
vue-cli项目配置多环境的详细操作过程
Oct 30 #Javascript
详解微信小程序中组件通讯
Oct 30 #Javascript
vue移动端项目缓存问题实践记录
Oct 29 #Javascript
vue 使用vue-i18n做全局中英文切换的方法
Oct 29 #Javascript
Element-UI踩坑之Pagination组件的使用
Oct 29 #Javascript
vue-router权限控制(简单方式)
Oct 29 #Javascript
You might like
PHP中,文件上传
2006/12/06 PHP
PHP常用函数小技巧
2008/09/11 PHP
PHP时间戳与日期之间转换的实例介绍
2013/04/19 PHP
php实现的DateDiff和DateAdd时间函数代码分享
2014/08/16 PHP
PHP+Ajax验证码验证用户登录
2016/07/20 PHP
thinkPHP引入类的方法详解
2016/12/08 PHP
给Function做的OOP扩展
2009/05/07 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
2014/09/04 Javascript
可以浮动某个物体的jquery控件用法实例
2015/07/24 Javascript
Vue-Router实现页面正在加载特效方法示例
2017/02/12 Javascript
JS html时钟制作代码分享
2017/03/03 Javascript
AugularJS从入门到实践(必看篇)
2017/07/10 Javascript
在vue中给列表中的奇数行添加class的实现方法
2018/09/05 Javascript
微信小程序云开发详细教程
2019/05/16 Javascript
js实现随机数小游戏
2019/06/28 Javascript
express框架下使用session的方法
2019/07/31 Javascript
vue+elementui通用弹窗的实现(新增+编辑)
2021/01/07 Vue.js
[05:10]2014DOTA2国际邀请赛 通往胜利之匙赛场探秘之旅
2014/07/18 DOTA
9种python web 程序的部署方式小结
2014/06/30 Python
python实现的简单窗口倒计时界面实例
2015/05/05 Python
Python的math模块中的常用数学函数整理
2016/02/04 Python
简单实现python进度条脚本
2017/12/18 Python
python 创建一个空dataframe 然后添加行数据的实例
2018/06/07 Python
NLTK 3.2.4 环境搭建教程
2018/09/19 Python
用Python实现读写锁的示例代码
2018/11/05 Python
python远程连接MySQL数据库
2019/04/19 Python
基于python实现计算且附带进度条代码实例
2020/03/31 Python
C++:memset ,memcpy和strcpy的根本区别
2013/04/27 面试题
关于青春的演讲稿
2014/05/05 职场文书
课前一分钟演讲稿
2014/08/26 职场文书
我的1919观后感
2015/06/03 职场文书
2015年城管执法工作总结
2015/07/23 职场文书
Go使用协程交替打印字符
2021/04/29 Golang
Java数据结构之链表相关知识总结
2021/06/18 Java/Android
「偶像大师 MILLION LIVE!」七尾百合子手办开订
2022/03/21 日漫
进阶篇之linux环境下安装MySQL数据库
2022/04/09 MySQL