使用vue.js制作分页组件
学习了vue.js一段时间,拿它来做2个小组件,练习一下。
我这边是用webpack进行打包,也算熟悉一下它的运用。
源码放在文末的github地址上。
首先是index.html
<!DOCTYPEhtml> <html> <head> <title>Page</title> <styletype="text/css"> *{ margin:0; padding:0; font-family:'OpenSans',Arial,sans-serif; } .contianer{ width:50%; height:auto; margin:20pxauto; } article{ margin-bottom:50px; } </style> </head> <body> <divclass='contianer'> <article> 文章内容... </article> <divid='main'> <app></app> </div> </div> <scripttype="text/javascript"src='bundle.js'></script> </body> </html>
我将app这个组件放在<divid='main'></div>内
通过webpack打包后,入口的js文件是entry.js,用来引入app.vue组件
entry.js
letVue=require('vue'); importAppfrom'./components/app'; letapp_vue=newVue({ el:'#main', components:{ app:App } });
接下来看下这个app组件
<styletype="text/css"scoped> </style> <template> <comment:cur-page-index="curPageIndex":each-page-size="eachPageSize":comment-url="commentUrl" :comment-params="commentParams":comment-is-sync="commentIsSync"> </comment> <page:cur-page-index.sync="curPageIndex":each-page-size="eachPageSize":page-url="pageUrl" :page-params="pageParams":page-is-sync="pageIsSync"> </page> </template> <scripttype="text/javascript"> importCommentfrom'./comment'; importPagefrom'./page'; exportdefault{ data(){ return{ curPageIndex:1, eachPageSize:7, } }, components:{ comment:Comment, page:Page }, } </script>
它有2个子组件,分别是comment.vue和page.vue,通过动态绑定数据,进行父子间组件通信,我是这样认为的,对于当前在第几页应当由page.vue传递给app.vue,所以这里我们使用双向绑定,其余的如params,url,isSync,即向后台请求数据的东西以及是否同步或异步操作<当然,这里我还没有测试过后台数据,目前是直接js生成静态数据>。
接下来,看下comment.vue评论组件
<styletype="text/css"scoped> .comt-mask{ opacity:0.5; } .comt-title{ } .comt-line{ width:100%; height:2px; background-color:#CCC; margin:10px0; } .comt-wrap{ } .comt-user{ float:left; } .comt-img{ width:34px; height:34px; border-radius:17px; } .comt-context{ margin:00060px; } .comt-name{ color:#2B879E; margin-bottom:10px; font-size:18px; } </style> <template> <divv-if="hasComment":class="{'comt-mask':loading}"> <h3class='comt-title'>{{totalCommentCount}}条评论</h3> <divclass="comt-line"></div> <divclass="comt-wrap"v-for="commentofcommentArr"> <divclass="comt-user"> <imgsrc='{{comment.avatar}}'class="comt-img"/> </div> <divclass="comt-context"> <pclass="comt-name">{{comment.name}}</p> <p> {{comment.context}} </p> </div> <divclass="comt-line"></div> </div> </div> </template> <scripttype="text/javascript"> import{getCommentData,getTotalCommentCount}from'./getData'; exportdefault{ props:{ curPageIndex:{ type:Number, default:1, }, eachPageSize:{ type:Number, default:7, }, commentUrl:{ type:String, default:'', }, commentParams:{ type:Object, default:null, }, commentIsSync:{ type:Boolean, default:true, }, }, data(){ return{ totalCommentCount:0, hasComment:false, loading:true, } }, computed:{ commentArr(){ this.loading=true; letres=getCommentData(this.commentUrl,this.commentParams,this.commentIsSync,this.curPageIndex,this.eachPageSize); this.loading=false; returnres; }, }, created(){ letcnt=getTotalCommentCount(this.commentUrl,this.commentParams); this.totalCommentCount=cnt; this.hasComment=cnt>0; } } </script>
这里的getData.js将在下面提到,是我们获取数据的位置。
loading:本意是在跳转页码加载评论时,对于当前评论加载0.5的透明度的遮罩,然后ajax通过它的回调函数来取消遮罩,现在这样就不能实现了,只能强行写下,然而是没有用的..
hasComment:comment组件第一次加载的时候,我们就去请求获得总共的数据长度,如果没有数据,则不显示comment组件布局内容
·curPageIndex·:通过父组件app传递下来,使用的是props
这些数据,我们都设置一个默认值与类型比较好。
page.vue
<styletype="text/css"scoped> .page{ text-align:center; margin:30px; } .page-btn{ color:gray; background-color:white; border:white; width:30px; height:30px; margin:5px; font-size:18px; outline:none; } .page-btn-link{ cursor:Crosshair; } .page-btn-active{ border:1pxsolidgray; border-radius:15px; } </style> <template> <divclass="page"> <buttonv-for="pageIndexofpageArr"track-by='$index':class="{'page-btn':true,'page-btn-active': this.curPageIndex===pageIndex,'page-btn-link':checkNum(pageIndex)}" @click="clickPage(pageIndex)"> {{pageIndex}} </button> </div> </template> <scripttype="text/javascript"> import{getTotalPageCount}from'./getData'; exportdefault{ props:{ totalPageCount:{ type:Number, default:0, }, curPageIndex:{ type:Number, default:1, }, eachPageSize:{ type:Number, default:7, }, pageAjcn:{ type:Number, default:4, }, pageUrl:{ type:String, default:'', }, pageParams:{ type:Object, default:null, }, pageIsSync:{ type:Boolean, default:true, } }, data(){ return{ } }, computed:{ pageArr(){ letst=1, end=this.totalPageCount, cur=this.curPageIndex, ajcn=this.pageAjcn, arr=[], left=Math.floor(ajcn/2), right=ajcn-left; if(end==0||cur==0){ returnarr; }else{ console.log(st,end,cur,left,right); arr.push(st); console.log(st+1,cur-left); if(st+1<cur-left){ arr.push('...'); } for(leti=Math.max(cur-left,st+1);i<=cur-1;++i){ arr.push(i); } if(cur!=st){ arr.push(cur); } for(leti=cur+1;i<=cur+right&&i<=end-1;++i){ arr.push(i); } if(cur+right<end-1){ arr.push('...'); } if(end!=cur){ arr.push(end); } returnarr; } } }, methods:{ clickPage(curIndex){ if(Number.isInteger(curIndex)){ this.curPageIndex=curIndex; } }, checkNum(curIndex){ returnNumber.isInteger(curIndex); } }, created(){ this.totalPageCount=getTotalPageCount(this.pageUrl,this.pageParams,this.pageIsSync, this.eachPageSiz); } } </script>
主要是个对于组件事件的运用,=最常见的click事件,以及class与style的绑定,根据curPageIndex与this.pageIndex来比较,判断是否拥有这个class,通过computed计算属性,来获得页码数组因为会根据当前页有所变化,created的时候计算出总页码。
最后一个是目前生成获取静态数据的js文件.
//letdata={ //avatar:'',头像 //name:'',用户名 //context:'',评论内容 //} letdataArr=[]; functionrandomStr(len){ returnMath.random().toString(36).substr(len); } functioninitData(){ for(vari=0;i<45;++i){ let_avator="./resources/"+i%7+".jpg"; let_name=randomStr(20); let_context=randomStr(2); dataArr.push({ avatar:_avator, name:_name, context:_context }); } } if(!dataArr.length){ initData(); } exportfunctiongetCommentData(url='',params=null,isSync=true,curPageIndex=1,eachPageSize=7){ /*ajax*/ letst=(curPageIndex-1)*eachPageSize; letend=st+eachPageSize; returndataArr.slice(st,end); } exportfunctiongetTotalCommentCount(url='',params=null,isSync=true){ /*ajax*/ returndataArr.length; } exportfunctiongetTotalPageCount(url='',params=null,isSync=true,eachPageSize=7){ /*ajax*/ returnMath.floor((dataArr.length+eachPageSize-1)/eachPageSize); }
就这样了吧。
github地址