前言
专注拖控件6年的C#程序员,迫于某种原因做起了前端开发,然后发现纯前端写起来要人命啊,所有的页面交互逻辑全是JS代码控制,写起来好难受。幸亏我JS功底深厚(自恋中……别打扰我……),很快就适应了,不然真的被搞死。
不过写到后面发现,纯JS控制用户交互,体验效果比aspx页面好多了。页面样式虽然是自己手写的,没用什么前端框架,但是用的Vue数据框架啊,然后发现Vue有组件开发模式,就想着是不是可以把原来ascx控件变成组件,这样写前端也变成拖控件了(PS:虽然是写标签),但开发效率肯定提升很大啊。
于是开始折腾启分页组件,因为使用次数高,而且也是最麻烦的一个,就试着把原来的ascx分页组件变成前端的,前面我写过一篇分页算法,这里我直接改成JS代码,这也是分页组件最核心的代码。
正文
首先,遵循Vue的组件规范,定义组件模板,并进行全局注册,基础知识不知道的请看这里,代码如下:
//注册Vue组件 Vue.component('x-paging', { props: ['codelist', 'total', 'pagelist'], template: '<div id="xpaging" class="pagenum"><span class="pagemsg">每页 ' + '<select id="pagesize" name="pagesize" onchange="XPaging.Api.ChangePageSize(this)">' + '<option v-bind:selected="code.selected?\'selected\':\'\'" v-for="code in codelist">{{code.pagesize}}</option>' + '</select>条 ' + '共<span class="number">{{total}}</span>条记录</span>' + '<a v-bind:class="page.ClassName" href="javascript:;" v-for="page in pagelist" v-on:click="XPaging.Api.PageTurn(page.Value)">{{page.Code}}</a></div>' });
这里使用三个prop变量进行数据的交互,codelist:每页数据大小集合,俗称pagesize;total:总记录数;pagelist:页码集合,就是第一页,第二页,第三页……
需要注意的是Vue定义组件,必须用一个标签包括起来,不然组件无法生效。
其次,就是组件的样式,代码如下:
/* 分页控件样式库 */ .pagenum { float: left; height: 26px; line-height: 26px; font-size: 14px; margin-top: 8px; margin-bottom: 7px; vertical-align: middle; } /*页码格子*/ .pagenum a { text-decoration: none; text-align: center; display: block; float: left; height: 16px; line-height: 16px; padding: 5px 7px 5px 7px; vertical-align: middle; min-width: 16px; border-radius: 2px; margin-right: 5px; } .pagenum a:link, a:visited { text-decoration: none; } .pagenum a:hover, a:active { text-decoration: none; } .pagenum a:hover { background-color: #f15a22; opacity: .7; filter: alpha(opacity=70); color: #ffffff; } /*总记录数*/ .number { color: #F30; margin-left: 5px; margin-right: 5px; } /*每页记录数*/ .pagemsg { text-align: center; display: block; float: left; height: 26px; line-height: 26px; margin-right: 10px; vertical-align: middle; } /*当前页码*/ .currindex { color: #FFF; background: #009ad6; } /*侯选页*/ .waitpage { color: #4f5555; background: #F0f0f0; } .pagenum select { margin-right: 4px; height: 22px; padding: 0px 0px; font-size: 13px; font-weight: bold; color: #F30; }
再次,就是为了统一pagesize,和默认的页面大小,我将其写入了一个json文件中。
为什么要这样呢?就是因为设计时,此控件会记录用户设置的页面大小,当打开其他页面或者刷新当前页面时,会默认设置用户上次选择的页面大小,代码如下:
{
"XPageSize": [
{
"pagesize": 2,
"selected": false
},
{
"pagesize": 5,
"selected": false
},
{
"pagesize": 10,
"selected": true
},
{
"pagesize": 15,
"selected": false
},
{
"pagesize": 20,
"selected": false
},
{
"pagesize": 25,
"selected": false
},
{
"pagesize": 30,
"selected": false
},
{
"pagesize": 40,
"selected": false
},
{
"pagesize": 50,
"selected": false
},
{
"pagesize": 100,
"selected": false
}
],
"XCodeNum": 5
}
pagesize和selected我就不说了,其中XCodeNum表示的是”连续页码显示的个数“,例如”1,2,3,4,5,……,10“连续显示5个页码。
最后,就是组件实现的JS代码了,核心方法有:
1.根据总记录数和连续页码显示个数,生成页码集合,就是pagelist;
2.获取json文件的数据,生成codelist,以及存储用户设置的页面大小,以便下次调用;
3.页面跳转,以及跳转后执行数据刷新方法等。
代码过长,只贴部分代码,要看完整的代码,及使用实例,请下载源码。
//插件默认参数 var options = { //连续页码显示个数(必须是奇数) ContinNO: 5, //索引页 CurrentPageIndex: 1, //总页数 PageCount: 0, //页面显示记录数 PaseSize: 0, //绑定数据方法名 DataBindFunc: "", //JSON配置文件路径 ConfigUrl: "../lib/XPaging/XPaingConfig.json" }; //用户调用接口 var XPagingInit = { //配置信息 config: function (opts) { //没有参数传入,直接返回默认参数 if (!opts) return options; //有参数传入,通过key将options的值更新为用户的值 for (var key in opts) { options[key] = opts[key]; } return this; }, //初始化插件 init: function (vueObj) { $.ajax({ type: "GET", url: options.ConfigUrl, async: false, dataType: 'Json', success: function (result) { options.ContinNO = result.XCodeNum; Xdata.SetPageSize(result.XPageSize, vueObj); Xdata.GetPageCount(vueObj.total); Xdata.GetPageList(vueObj); }, error: function (data, XMLHttpRequest, textStatus, errorThrown) { alert("分页控件初始化失败,返回信息:" + JSON.stringify(data)); } }); return this; }, //获取当前页索引 GetCurrentPageIndex: function () { return options.CurrentPageIndex; }, //获取页面大小 GetPageSize: function () { return options.PaseSize; } };
最终的运行效果如下图: