你还在这样使用layui?【layui-table篇】

1.前言:

layui用了几年,这个框架十分适合我们后台人员开发。简单易用,用的较多的模块肯定是table模块和form模块了。但是在一个开发团队中,不同的人开发水平的差异,如果没有调用统一的公共方法,那就会造成很多样式的不同和公共的bug出现到不同的页面 从而出现耗费过多的精力修改bug。所以我们需要做的是统一样式和方法的调用,将其二次封装以便于开发人员的调用。另一方面也能减少代码的冗余量。

2. layui-table的封装

2.1.页面构成:一般在页面的table的构成如下: 搜索区 头部工具栏 和table主体【包含对行和列 事件的处理】

file
需要的几点是: ‘’兼容‘’ 官方table的参数options 设置了默认值 和可以覆盖默认值 、 支持搜索方法(search/reset 【代表重置搜索】) 和 能够获取的layui的table组件

对外提供的方法

file

2.2.从使用案例去解析每个方法

如下列所示,首先是创建对象【这个是我封装的table组件对象】,重点在于init方法是初始化整个table


    <script>
            var grid = new LayDataTable();

            grid.init({
                elem: '#listTable',
                data: resDt.data,
         //  defaultToolbar: ['filter', 'print', 'exports', 
                //  {
                //     title: 'wifi' //标题
                //     ,layEvent: 'wifi' //事件名,用于 toolbar 事件中使用
                //     ,icon: 'layui-icon-wifi' //图标类名
                //  },
                //  {
                //      title: '授权' //标题
                //      ,layEvent: 'auz' //事件名,用于 toolbar 事件中使用
                //      ,icon: 'layui-icon-auz' //图标类名
                //   }
                // ],
                toolbar: 'default', //开启工具栏,此处显示默认图标,可以自定义模板,详见文档       
                title: '用户表',
                totalRow: true, //开启合计行             
                cols: [
                    [
                        //...
                    ]
                ]
            }, function(checkStatus, event) {
                console.log(checkStatus, event);
            }, function(obj) {
                console.log(obj);
            }, "searchId");


            //搜索的方法
            function searchF() {
                grid.search();
            }

            //重置
            function reset() {
                grid.reset();
            }
        </script>

** init 方法**

init 方法的入参有四个分别是table的options【这个参考layui官网】、头部工具栏的点击事件、table行点击事件 和搜索区的id【当然搜索区用的也是layui的组件 如input select等等】

file
file

需要修改跟你项目匹配的几个地方,主要是table的options的参数 :parseData【因为不同后端返回的json的key不太一样,需要按layui固定的格式去赋值】和 request:默认向后端传递分页参数命名【这个部分是向你的项目靠拢】 还有就是 排序部分,这个在监听排序事件里面 【如上图标记】,这点也是能渠道前端的排序字段和方式 至于怎么向后端传参的,可以根据后端设置的来。这点跟request一样 ,是根据后端配置而不是根据layui的格式来制定的。

搜索区的id设置的原因是,初始化和后面搜索都需要统一组装参数,如果这点也需要每次都写一遍,不封装那要写累死,尤其是那种死心眼的开发者,一个个获取input 和select值的这种行为。

reset 方法:

file

这里用到了表格渲染,因为重置了参数 单选框 多选框 下拉框的表现还是原来的样子,需要重新渲染下。为了区分开区域 这里只渲染搜索区的控件。

当reset带了参数时,这部分参数注入到搜索参数里面去。参数格式为:{}.

3. 完整的js:


var LayDataTable = (function() {
    var table;
    var l_options;
    var l_searchConfig;
    var currentTable;
    var $;
    var whereData={};//搜索条件
    var form;

    function init(_options, headEvenFun = null, rowEvenFun = null, searchConfig = {}) {
        var _this = this;

        //设置默认项
        _options.elem = _options.elem || "";
        _options.height = _options.height || 700;

        //默认分页配置
        if (typeof(_options.page) != "boolean") {
            _options.page = _options.page ||{};
            _options.page = Object.assign({
                first: '首页',
                prev: '上一页',
                next: '下一页',
                last: '尾页',
                groups: '6',
                layout: ['count', 'first', 'prev', 'page', 'next', 'limit', 'refresh', 'skip'],
                theme: '#fe0627'
            },_options.page);
        }

        var options = Object.assign({
            title: '',
            defaultToolbar: ['filter', 'print'],
            limits: [10, 50, 100],
            limit: 10, //每页默认显示的数量
            skin: 'row', //表格风格
            even: typeof(_options.even)=='boolean'?_options.even:true, //开启隔行背景
            size: 'lg', //小尺寸的表格
            text:{
                none: '暂无相关数据' //默认:无数据。注:该属性为 layui 2.2.5 开始新增
            },
            parseData:function(res) { //res 即为原始返回的数据
                return {
                    //这部分最后使用全局配置 根据实际业务修改
                    "code": res.status, //解析接口状态
                    "msg": res.message, //解析提示文本
                    "count": res.total, //解析数据长度
                    "data": res.data.item //解析数据列表
                };
            },
            request:{   //默认请求参数 根据实际业务修改
                pageName: 'start', //页码的参数名称,默认:page
                limitName: 'length' //每页数据量的参数名,默认:limit
            }
        },_options);

        
        var elemDom = document.getElementById(options.elem.substr(1));
        var tableFilter = elemDom.getAttribute("lay-filter");

        l_options = options;
        //搜索条件
        if (searchConfig) {
            l_searchConfig =searchConfig;
        }


        layui.use(['table', 'jquery','form'], function() {
            table = layui.table;
            $ =layui.$;
            setParams();
            l_options.where = whereData;
            //第一个实例
            currentTable = table.render(options);
            form= layui.form;

            //头工具栏事件
            if (typeof(headEvenFun) == "function") {
                table.on('toolbar(' + tableFilter + ')', function(obj) {
                    headEvenFun(table.checkStatus(obj.config.id), obj.event);
                });
            }

            //监听行工具事件
            if (typeof(rowEvenFun) == "function") {
                table.on('tool(' + tableFilter + ')', function(obj) {
                    rowEvenFun(obj);
                });
            }
            
            //监听排序事件 
            table.on('sort('+l_options.elem.replace("#","")+')', function(obj){ //注:sort 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"         
              
              table.reload(l_options.elem.replace("#",""), {
                initSort: obj //记录初始排序,如果不设的话,将无法标记表头的排序状态。
                ,where: { //请求参数                  (注意:这里面的参数可任意定义,并非下面固定的格式)---》根据实际业务修改
                   field: obj.field //排序字段
                  ,order: obj.type //排序方式
                }
              });
              
            });

        });

    }

    function search() { //搜索的方法     
        setParams();
        l_options.where = whereData;
        currentTable.reload(l_options);
    }

    function getTable() { //获取table
        return table;
    }
    
    function setParams(){// 设置参数
        var type;
        var searchId = typeof(l_searchConfig)==='object'?l_searchConfig.searchId:l_searchConfig;
        
        $("#"+searchId+" input,#"+searchId+" select").each(function(ind, item) {
            type = $(item).attr("type");
            if ($(item).attr("name")) {
                if (type == 'radio' || type == 'checkbox') {
                    whereData[$(item).attr("name")] = $("input[name='" + $(item).attr("name") + "']:checked").val() || '';
                } else {
                    whereData[$(item).attr("name")] = $(item).val() || '';
                }
            }
        })
    }

    function reset(whereParams) { //重置搜索
        var type;
        whereData = {};
        l_options.where={};
        var searchId = typeof(l_searchConfig)==='object'?l_searchConfig.searchId:l_searchConfig;
        
        $("#"+searchId+" input,#"+searchId+" select").each(function(ind, item) {
            type = $(item).attr("type");
            if ($(item).attr("name")) {
                if (type == 'hidden') {
                    whereData[$(item).attr("name")] = $(item).val() || '';
                } else if (type == 'radio' || type == 'checkbox') {
                    $(item).attr("checked", false);
                    whereData[$(item).attr("name")] = '';
                } else {
                    whereData[$(item).attr("name")] = '';
                    $(item).val("");                    
                }
            }
        
        });
        Object.assign(whereData,whereParams||{}) ;
        //局部刷新 搜索区  最顶部div 的 class="layui-form" 
        //需要搭配 lay-filter,并且lay-filter的值
        //一定要与 seachConfig里面searchId的值一样
        form.render('select',searchId);
        form.render('radio',searchId);
        form.render('checkbox',searchId);
    
        
        currentTable.reload({
            where: whereData,
            page:{
                 curr: 1//重新从第 1 页开始
            }
        });
    }


    //对象方法  [我的理解]
    return function() {
        this.init = init;
        this.search = search; //搜索
        this.reset = reset; //重置搜索
        this.getTable = getTable;
    }
})();


//属性使您有能力向对象添加属性和方法
LayDataTable.prototype = {
}

源码

file

本文来源于:程序员ken,专属平台有csdn、思否(SegmentFault)、 简书、 开源中国(oschina)、掘金,转载请注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容