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

2018-10-30 48 fozero

前言

上篇文章中,已经使用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文章

jQuery的Ajax时无响应数据的解决方法
May 25 46
跟我学习javascript的Date对象
Nov 19 42
浅析JS操作DOM的一些常用方法
May 13 48
jQuery向父辈遍历的简单方法
Sep 18 42
Angular2学习笔记——详解NgModule模块
Dec 02 51
JS和jQuery通过this获取html标签中的属性值(实例代码)
Sep 11 27
javascript实现下拉菜单效果
Feb 09 39
手机访问当前页面