使用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地址