Skip to content

使用心得

白開水 edited this page Mar 27, 2023 · 2 revisions

layuiMini: http://layuimini.99php.cn/

官方文档: http://easyadmin.99php.cn/docs/

layui镜像站: https://cshaptx4869.github.io/mypage/layui/index.html

问题集

Layui 源码改动

easyadmin 总计有两处 layui 2.5.6 源码修改:

  • src/lay/modules/table.js
parseTempData = function(item3, content, tplData, text){ //表头数据、原始内容、表体数据、是否只返回文本
  var str = item3.templet ? function(){
    return typeof item3.templet === 'function' 
      ? item3.templet(tplData, item3) // 改动处:此处需额外传入 item3 参数
      : laytpl($(item3.templet).html() || String(content)).render(tplData) 
  }() : content;
  return text ? $('<div>'+ str +'</div>').text() : str;
}
  • src/layui.js
search: function(){
  var obj = {}
  ,search = (href 
    ? function () { var path = (href.match(/\?.+/) || [])[0] || ''; return path.replace(/\#.+/, "")} () // 改动处:此处增加#后面的字符串去除
    : location.search
  ).replace(/^\?+/, '').split('&'); //去除 ?,按 & 分割参数
  
  //遍历分割后的参数
  that.each(search, function(index, item){
    var _index = item.indexOf('=')
    ,key = function(){ //提取 key
      if(_index < 0){
        return item.substr(0, item.length);
      } else if(_index === 0){
        return false;
      } else {
        return item.substr(0, _index);
      }
    }(); 
    //提取 value
    if(key){
      obj[key] = _index > 0 ? item.substr(_index + 1) : null;
    }
  });
  
  return obj;
}()

Tips:

  • 修改源码后记得重新 gulp 打包
  • node 版本不能太高,否则会报 fs.js:42 } = primordials; 错误,因为 node 12.0 的版本之后(包括12.0版本)不支持 gulp4.0 之前的版本,实测本地使用 node11 没有报错, node16 就有问题
  • 这样重新打包后获得的 layui.all.js 文件就和 easyadmin 中的完全一样了

表格渲染

Q: 渲染 table 的自定义模板 templet 属性的时候,比如渲染图片。在easyadmin 中可以使用 {templet: ea.table.image} 配置渲染 , 他会自动传入两个参数 data, option 。而在 layui 的 {templet: function(d){}} 配置的回调函数中只会传入第一个参数 d。 easyadmin 中他是怎么处理的,会传入2个参数.. A: easyadmin 中修改了 layui.all.js 和 table.js 源文件

function(){return"function"==typeof e.templet?e.templet(l):i(t(e.templet).html()||String(a)).render(l)}()

return"function"==typeof e.templet ? e.templet(l) : i(t(e.templet).html() || String(a)).render(l)e.templet(l)e.templet(l, e)

内置插件说明

tableSelect 下拉表格选择器

基于 layui 扩展组件 tableSelect 修改

修改点

  1. 增加容器最小宽度参数 width
  2. 增加多搜索条件参数 searchType、searchList
var tableSelect = layui.tableSelect;
tableSelect.render({
	elem: '#demo',	//定义输入框input对象
	checkedKey: 'id', //表格的唯一建值,非常重要,影响到选中状态 必填
	searchKey: 'keyword',	//搜索输入框的name值 默认keyword
	searchPlaceholder: '关键词搜索',	//搜索输入框的提示文字 默认关键词搜索
	table: {	//定义表格参数,与LAYUI的TABLE模块一致,只是无需再定义表格elem
		url:'',
		cols: [[]]
	},
	done: function (elem, data) {
		//选择完后的回调,包含2个返回值 elem:返回之前input对象;data:表格返回的选中的数据 []
		//拿到data[]后 就按照业务需求做想做的事情啦~比如加个隐藏域放ID...
	},
  
  //新增参数
  width: 530, //容器最小宽度
  height: 315, //容器高度
  searchType: 'more', //是否多条件检索
})
//默认值
//只需要在触发input上添加 ts-selected="1,2,3" 属性即可 值需与checkedKey对应

step-lay 分步表单

基于 step-lay 修改

修改点:

  1. layui.link(layui.cache.base + 'step-lay/step.css');

iconPickerFa 图标选择器

基于 iconPicker 图标选择器修改而来

treetable 树状表格

基于 treetable-lay 插件。 HTML

<link rel="stylesheet" href="__STATIC__/plugs/lay-module/treetable-lay/treetable.css?v={:time()}" media="all">
<style>
    .layui-btn:not(.layui-btn-lg ):not(.layui-btn-sm):not(.layui-btn-xs) {
        height: 34px;
        line-height: 34px;
        padding: 0 8px;
    }
</style>
<div class="layuimini-container">
    <div class="layuimini-main">
        <table id="currentTable" class="layui-table layui-hide"
               data-auth-add="{:auth('system.menu/add')}"
               data-auth-edit="{:auth('system.menu/edit')}"
               data-auth-delete="{:auth('system.menu/delete')}"
               lay-filter="currentTable">
        </table>
    </div>
</div>
<script type="text/html" id="toolbar">
    <button class="layui-btn layui-btn-sm layuimini-btn-primary" data-treetable-refresh><i class="fa fa-refresh"></i> </button>
    <button class="layui-btn layui-btn-normal layui-btn-sm {if !auth('system.menu/add')}layui-hide{/if}" data-open="system.menu/add" data-title="添加" data-full="true"><i class="fa fa-plus"></i> 添加</button>
    <button class="layui-btn layui-btn-sm layui-btn-danger {if !auth('system.menu/del')}layui-hide{/if}" data-url="system.menu/del" data-treetable-delete="currentTableRenderId"><i class="fa fa-trash-o"></i> 删除</button>
</script>

JS

define(["jquery", "easy-admin", "treetable"], function ($, ea) {

    var table = layui.table,
        treetable = layui.treetable;

    var init = {
        table_elem: '#currentTable',
        table_render_id: 'currentTableRenderId',
        index_url: 'system.menu/index',
        add_url: 'system.menu/add',
        delete_url: 'system.menu/delete',
        edit_url: 'system.menu/edit',
        modify_url: 'system.menu/modify',
    };

    var Controller = {
        index: function () {

            var renderTable = function () {
                layer.load(2);
                treetable.render({
                    treeColIndex: 1, //树状列索引 从0开始
                    treeSpid: 0, //数据初始id值
                    treeIdName: 'id', //数据树状id字段的名称
                    treePidName: 'pid', //数据树状父id字段的名称
                    treeDefaultClose: false, //是否默认折叠
                    treeLinkage: false, // 父级展开时是否自动展开所有子级
                    homdPid: 99999999, //主页pid
                    url: ea.url(init.index_url),
                    elem: init.table_elem,
                    id: init.table_render_id,
                    toolbar: '#toolbar',
                    page: false,
                    skin: 'line',

                    // @todo 不直接使用ea.table.render(); 进行表格初始化, 需要使用 ea.table.formatCols(); 方法格式化`cols`列数据
                    // 为什么需要格式化?因为 ea.table.tool 会有用到列的 init 属性 var elem = option.init.table_elem || init.table_elem; 做权限的判断 
                    cols: ea.table.formatCols([[
                        {type: 'checkbox'},
                        {field: 'title', width: 250, title: '菜单名称', align: 'left'},
                        {field: 'icon', width: 80, title: '图标', templet: ea.table.icon},
                        {field: 'href', minWidth: 120, title: '菜单链接'},
                        {
                            field: 'is_home',
                            width: 80,
                            title: '类型',
                            templet: function (d) {
                                if (d.pid === 99999999) {
                                    return '<span class="layui-badge layui-bg-blue">首页</span>';
                                }
                                if (d.pid === 0) {
                                    return '<span class="layui-badge layui-bg-gray">模块</span>';
                                } else {
                                    return '<span class="layui-badge-rim">菜单</span>';
                                }
                            }
                        },
                        {field: 'status', title: '状态', width: 85, templet: ea.table.switch},
                        {field: 'sort', width: 80, title: '排序', edit: 'text'},
                        {
                            width: 200,
                            title: '操作',
                            templet: ea.table.tool,
                            operat: [
                                [{
                                    text: '添加下级',
                                    url: init.add_url,
                                    method: 'open',
                                    auth: 'add',
                                    class: 'layui-btn layui-btn-xs layui-btn-normal',
                                    extend: 'data-full="true"',
                                }, {
                                    text: '编辑',
                                    url: init.edit_url,
                                    method: 'open',
                                    auth: 'edit',
                                    class: 'layui-btn layui-btn-xs layui-btn-success',
                                    extend: 'data-full="true"',
                                }],
                                'delete'
                            ]
                        }
                    ]], init),
                    done: function () {
                        layer.closeAll('loading');
                    }
                });
            };

            renderTable();

            $('body').on('click', '[data-treetable-refresh]', function () {
                renderTable();
            });

            $('body').on('click', '[data-treetable-delete]', function () {
                var tableId = $(this).attr('data-treetable-delete'),
                    url = $(this).attr('data-url');
                tableId = tableId || init.table_render_id;
                url = url != undefined ? ea.url(url) : window.location.href;
                var checkStatus = table.checkStatus(tableId),
                    data = checkStatus.data;
                if (data.length <= 0) {
                    ea.msg.error('请勾选需要删除的数据');
                    return false;
                }
                var ids = [];
                $.each(data, function (i, v) {
                    ids.push(v.id);
                });
                ea.msg.confirm('确定删除?', function () {
                    ea.request.post({
                        url: url,
                        data: {
                            id: ids
                        },
                    }, function (res) {
                        ea.msg.success(res.msg, function () {
                            renderTable();
                        });
                    });
                });
                return false;
            });

            ea.table.listenSwitch({filter: 'status', url: init.modify_url});

            ea.table.listenEdit(init, 'currentTable', init.table_render_id, true);

            ea.listen();
        },
        add: function () {
            ea.listen(function (data) {
                return data;
            }, function (res) {
                ea.msg.success(res.msg, function () {
                    var index = parent.layer.getFrameIndex(window.name);
                    parent.layer.close(index);
                    parent.$('[data-treetable-refresh]').trigger("click");
                });
            });
        },
        edit: function () {
            ea.listen(function (data) {
                return data;
            }, function (res) {
                ea.msg.success(res.msg, function () {
                    var index = parent.layer.getFrameIndex(window.name);
                    parent.layer.close(index);
                    parent.$('[data-treetable-refresh]').trigger("click");
                });
            });
        },
    };
    return Controller;
});

扩展插件方法

xm-Select

使用文档

requireJs 中引入报 xmSelect is not defined 修改源码: define(xmSelect) 改为 define(function() {return t.c})

"object" === ("undefined" == typeof exports ? "undefined" : _typeof(exports)) ? e.exports = t.c : "function" == typeof define && n(221) ? define(function() {return t.c}) : window.layui && layui.define && layui.define((function (e) { e("xmSelect", t.c)}))

1、下载插件并放置到 plugs/lay-module/xmSelect/xm-select.js** **然后在 config-admin.jspaths 属性中增加如下代码。

"xmSelect": ["plugs/lay-module/xmSelect/xm-select"]

2、使用 在 xx.js 中使用

define(["jquery", "easy-admin", "xmSelect"], function ($, ea, xmSelect) {
  console.log(xmSelect);
})

formSelect 4.x 多选框

使用文档

1、下载插件并放置到 plugs/lay-module/formSelects/formSelects-v4.js** **然后在 config-admin.js 的 paths 属性中增加如下代码。

"formSelects": ["plugs/lay-module/formSelects/formSelects-v4"]

2、使用 引入 css

<link rel="stylesheet" href="__STATIC__/plugs/lay-module/formSelects/formSelects-v4.css?v={$version}" media="all">

在 xx.js 中使用

define(["jquery", "easy-admin", "formSelects"], function ($, ea, formSelects) {
  console.log(formSelects);
})

treeTable 树形表格

1、下载插件并放置到 plugs/lay-module/treeTable/treeTable.js** **然后在 config-admin.js 的 paths 属性中增加如下代码。

"treeTable": ["plugs/lay-module/treeTable/treeTable"],

2、使用

define(["jquery", "easy-admin", "treeTable"], function ($, ea) {
   var treeTable = layui.treeTable;
   treeTable.render({
      elem: '#tree-table',// 原始 table 容器的选择器, 必须
      url: 'data/table-tree.json',// 获取数据接口,url和data参数必须设置一个 
      data: [{},{},{},...],
      icon_key: 'title',// 三角符号的字段名,必须
      top_value: 0,// 顶级 pid 值
      primary_key: 'id',
      parent_key: 'pid',
      hide_class: 'layui-hide',
      icon: {
        open: 'layui-icon layui-icon-triangle-d',
        close: 'layui-icon layui-icon-triangle-r',
        left: 16,
      },
      cols: [
              {
                key: 'title',
                title: '名称',
                width: '100px',
                template: function(item){return '显示内容'}
      				},
       				{}
       ],
      checked: {
        key: 'id',
        data: [1,4,10],
      },
      is_click_icon: false, //是点击列收缩还是点击三角图标
      is_checkbox: false, //是否显示 checkbox
      is_cache: true,
      end: function(e){},
    });
}

i18n

1、下载地址config-admin.js 的增加如下代码

var languageCookie = document.cookie.match(/language=(.*?);/);
var language = languageCookie ? languageCookie[1] : 'zh';

paths: {
    "i18n": ["plugs/rq-module/i18n"],
},
config: {
    i18n: {
        locale: language
    }
}

2、使用 image.png

//message.js
define({
    zh: true,
    en: true
});

//zh/message.js
define({
    edit: '编辑'
});

//en/message.js
define({
    edit: 'Edit'
});

nls/messages 针对的是 **_require_**.config 中的 baseUrl

define(["jquery", "easy-admin", "i18n!nls/messages"], function ($, ea, i18n) {
		console.log(i18n.edit) //编辑
})

jquery-cookie

1、下载地址config-admin.js 的增加如下代码

paths: {
    "jquery-cookie": ["plugs/jq-module/jquery.cookie.min"],
},
shim: {
    "jquery-cookie": ["jquery"]
},

2、使用

define(["jquery", "easy-admin", "jquery-cookie"], function ($, ea, i18n) {
		$.cookie('name', 'value');
})

PR

https://github.com/zhongshaofa/easyadmin/pulls/cshaptx4869

Fix: 解决非默认高度时,固定列行错位问题

table: {
	render: function() {
  	// 解决非默认高度时,固定列行错位问题
    options.done = options.done || function () {
      $(".layui-table-main tr").each(function (index, val) {
        $(".layui-table-fixed").each(function () {
          $($(this).find(".layui-table-body tbody tr")[index]).height($(val).height());
        });
      });
      $(".layui-table-header tr").each(function (index, val) {
        $(".layui-table-fixed").each(function () {
          $($(this).find(".layui-table-header thead tr")[index]).height($(val).height());
        });
      });
    };
  }
}