• 分页组件


    某日,在公司写一个简单的活动页面,活动见链接 ,这个页面业务叫简单,核心就是一个分页内容,活动很快就搞定了,然后呢,就整理分页功能,写成一个插件。

      嗯~~~说弄就弄。

      首先呢,先将页面分成两个区域:内容展示区和控件按钮(分页,上下页,跳转页等)展示区

    <div class="page-wrapper">
      <div class="page-content">
        内容区域
      </div>
      <div class="control-wrapper">
        分页按钮区域
      </div>
    </div>

      页面结构是弄好了,那么下面就要开始写JS了。

      之前呢,公司也有类似的分页功能的功能函数,其采用的做法是:

        1. 请求接口获取所有的数据

        2. 将所有数据分页渲染到几个div中,类似的方式

        3. 然后用 tab 页的形式,控制 div 显示隐藏 

      这样的话,如果数据比较少还是ok的,但如果数据比较多的话,会出现几个问题,

        1. 接口请求时间问题

        2. 数据渲染时间问题(采用的 dom 渲染方式,这样页面需要较长的时间才能加载显示出来,用户体验就很差)

      

    解决办法呢?

      一、接口改成分页请求

        1.  前端负责写一个模板页面,然后将分页模板交给后端;前端只需负责分页按钮的状态,给按钮加链接即可。(整个页面会刷新)

        2.  后端把总页数给前端,前端根据页码请求不同页面的内容

      二、优化渲染时间

        1. 把接口所有的数据请求出来

        2. 将所有数据分页,保存在一个对象中,如: { page: 1, content: .... }

        3. 分页渲染各个页面的内容

    在听到大佬的指点后,感觉自己的代码还是有问题的,故分享下思路和整体代码。后续优化完后,在对文章修改

    1、根据请求的数据,对数据进行分页保存。

    2、根据需求,在分页控制器内添加相应的html。

    3、渲染分页按钮和内容。

    当前完整代码如下。

    var Paganation = function (el, options) {
            /*
             * baseUrl          string      跳转链接(*)
             * curPage          number      当前页(*) 从1开始
             * totalPage        number      总页数(*)
             * arrow            boolean     是否有上下页
             * showLen          number      显示的按钮个数
             * pageDetail       boolean     是否显示具体的页码
             * isTail           boolean     首尾页
             * isShowInfo       boolean     是否显示页数详情
             * ellipsisClass    string      省略号类名
             * prefix           string      按钮类名前缀
             */
    
            this.el = el;
            let baseOptions = Object.assign({
                baseUrl: null,
                curPage: 1,
                totalPage: 100,
                isArrow: true,
                showNum: 10,
                prefix: 'page-',
                disabledClass: 'page-disabled',
                isTail: true,
                pageDetail: true,
                isShowInfo: true,
                ellipsisClass: ''
            }, options);
    
            /*
             * prev     string      上一页
             * next     string      下一页
             * start    string      首页
             * end      string      尾页
             * page     strign      具体的页码
             * info     string      页码详情
             */
            this.prevHTML = '';
            this.nextHTML = '';
            this.startHTML = '';
            this.endHTML = '';
            this.pageHTML = '';
            this.infoHTML = '';
    
            this._init(baseOptions);
        };
    
        Paganation.prototype = {
    
            constructor: Paganation,
    
            _analysisOptions: function (options) {
                for (let k in options) {
                    this[k] = options[k];
                }
            },
    
            _init: function (options) {
                this._analysisOptions(options);
    
                if (!this.baseUrl) {
                    throw new Error(`must set baseUrl`);
                }
    
                if (!this.el) {
                    throw new Error(`must set a page container`);
                };
    
                this._render();
            },
    
            // set html
            _create: function () {
                this.curPage = +this.curPage;
                this.totalPage = +this.totalPage;
                if (this.curPage < 1) this.curPage = 1;
                if (this.curPage > this.totalPage) this.curPage = this.totalPage;
                if (this.isArrow) this._createArrow();
                if (this.isTail) this._createTail();
                if (this.isShowInfo) this._createInfo();
                if (this.pageDetail) this._createPage();
            },
    
            // 上下页
            _createArrow: function () {
                const disabledClass = this.disabledClass;
                const prevUrl = this.curPage == 1 ? 'javascript:void(0);' : this.baseUrl + (this.curPage - 1);
                const nextUrl = this.curPage == this.totalPage ? 'javascript:void(0);' : this.baseUrl + (+this.curPage + 1);
                const prevDisabled = this.curPage == 1 ? disabledClass : '';
                const nextDisabled = this.curPage == this.totalPage ? disabledClass : '';
    
                this.prevHTML = '<a class="' + this.prefix + 'item ' + prevDisabled + '" href="' + prevUrl + '">上一页</a>';
                this.nextHTML = '<a class="' + this.prefix + 'item ' + nextDisabled + '" href="' + nextUrl + '">下一页</a>';
            },
    
            // 首尾页
            _createTail: function () {
                const disabledClass = this.disabledClass;
                const startUrl = this.curPage == 1 ? 'javascript:void(0);' : this.baseUrl + 1;
                const endUrl = this.curPage == this.totalPage ? 'javascript:void(0);' : this.baseUrl + this.totalPage;
                const startDisabled = this.curPage == 1 ? disabledClass : '';
                const endDisabled = this.curPage == this.totalPage ? disabledClass : '';
                this.startHTML = '<a class="' + this.prefix + 'item ' + startDisabled + '" href="' + startUrl + '">首页</a>';
                this.endHTML = '<a class="' + this.prefix + 'item ' + endDisabled + '" href="' + endUrl + '">尾页</a>';
            },
    
            // 页数详情
            _createInfo: function () {
                this.infoHTML = '<span class="' + this.prefix + 'total">共<i>' + this.totalPage + '</i>页</span><span class="' + this.prefix + 'cur">当前第<i>' + this.curPage + '</i>页</span>'
            },
    
            // 具体的页码
            _createPage: function () {
                let str = '';
                let self = this;
                let showNum = this.showNum;
                let totalPage = this.totalPage;
                let curPage = this.curPage;
                const prefix = this.prefix;
                const centerStr = '<span class="' + this.ellipsisClass + '">...</span>';
    
                let urlFn = function (i) {
                    return self.baseUrl + i;
                };
                let htmlStr = function (i) {
                    const endabled = self.curPage == i ? self.disabledClass : '';
                    return '<a class="' + prefix + 'item ' + endabled + '" href="' + urlFn(i) + '">' + i + '</a>';
                };
    
                if (showNum >= totalPage) {
                    for (let i = 1; i <= totalPage; i++) {
                        str += htmlStr(i)
                    }
                } else {
                    if (curPage < totalPage - showNum + 1) { //头部
                        for (let i = 0; i < showNum - 1; i++) {
                            str += htmlStr(+curPage + i);
                        }
                        str += centerStr + htmlStr(totalPage);
                    } else { // 尾部
                        for (let i = 1; i <= showNum; i++) {
                            str += htmlStr(totalPage - showNum + i);
                        }
                    }
                }
    
                this.pageHTML = str;
            },
    
            _goPage: function (i) {
                this.curPage = i;
                this._render();
            },
    
            _render: function () {
                this._create();
                this.el.innerHTML = this.infoHTML + this.startHTML + this.prevHTML + this.pageHTML + this.nextHTML + this.endHTML;
            }
        }
    

      

      

  • 相关阅读:
    uniApp 实现微信小程序和app视频播放flv格式视频监控
    uniapp 给子组件传值不及时显示
    uni-app 中$refs 在app中无法使用
    使用甘特图
    背景图片加蒙版,里面内容不受影响
    MyBatis 多对一操作
    在Maven项目中使用lombok
    MyBatis使用分页
    Log4j打印日志
    paramiko 下载文件
  • 原文地址:https://www.cnblogs.com/intangible/p/9084236.html
Copyright © 2020-2023  润新知