首页 > 编程 > JavaScript > 正文

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

2019-11-19 12:36:58
字体:
来源:转载
供稿:网友

前言

上篇文章中,已经使用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,totalPaging事件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实现仿百度前端分页效果附实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表