Skip to content

表格渲染

静态渲染

默认样式适合做 ssr 渲染

html
<body>
  <p>默认风格:</p>
  <table class="layui-table">
    <colgroup>
      <col style="width: 150px" />
      <col style="width: 150px" />
      <col />
    </colgroup>
    <thead>
      <tr>
        <th>人物</th>
        <th>民族</th>
        <th>格言</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>孔子</td>
        <td>华夏</td>
        <td>有朋至远方来,不亦乐乎</td>
      </tr>
      <tr>
        <td>孟子</td>
        <td>华夏</td>
        <td>穷则独善其身,达则兼济天下</td>
      </tr>
    </tbody>
  </table>
</body>

已有数据渲染

html
<body>
  <table class="layui-hide" id="ID-table-demo-data"></table>

  <script src="/static/layui.js"></script>
  <script>
    layui.use(function () {
      var table = layui.table;

      // 已知数据渲染
      var inst = table.render({
        elem: "#ID-table-demo-data",
        cols: [
          [
            //标题栏
            { field: "id", title: "ID", width: 80, sort: true },
            { field: "username", title: "用户", width: 120 },
            { field: "sign", title: "签名", minWidth: 160 },
            { field: "sex", title: "性别", width: 80 },
            { field: "city", title: "城市", width: 100 },
            { field: "experience", title: "积分", width: 80, sort: true },
          ],
        ],
        data: [
          {
            id: "10001",
            username: "张三1",
            sex: "男",
            city: "浙江杭州",
            sign: "人生恰似一场修行",
            experience: "116",
          },
          {
            id: "10002",
            username: "张三2",
            sex: "男",
            city: "浙江杭州",
            sign: "人生恰似一场修行",
            experience: "12",
            LAY_CHECKED: true,
          },
          {
            id: "10003",
            username: "张三3",
            sex: "男",
            city: "浙江杭州",
            sign: "人生恰似一场修行",
            experience: "65",
          },
          {
            id: "10004",
            username: "张三4",
            sex: "男",
            city: "浙江杭州",
            sign: "人生恰似一场修行",
            experience: "777",
          },
          {
            id: "10005",
            username: "张三5",
            sex: "男",
            city: "浙江杭州",
            sign: "人生恰似一场修行",
            experience: "86",
          },
          {
            id: "10006",
            username: "张三6",
            sex: "男",
            city: "浙江杭州",
            sign: "人生恰似一场修行",
            experience: "12",
          },
          {
            id: "10007",
            username: "张三7",
            sex: "男",
            city: "浙江杭州",
            sign: "人生恰似一场修行",
            experience: "16",
          },
          {
            id: "10008",
            username: "张三8",
            sex: "男",
            city: "浙江杭州",
            sign: "人生恰似一场修行",
            experience: "106",
          },
        ],
        // skin: 'line', // 表格风格
        // even: true,
        page: true, // 是否显示分页
        limits: [2, 5, 10, 15],
        limit: 5, // 每页默认显示的数量
        count: 100,
      });
    });
  </script>
</body>

已有数据渲染默认的情况下会自行在前端实现分页。如果想要与后端联动,则应该使用数据接口进行渲染。

自定义模版

自定义模版时,flask 的 jinja2 与 layui 的 tpl 模版语法冲突。比较好的解决办法是更改 jinja2 或者是 tpl 的语法。但是在这里我采用折中的方法,让 jinja2 转义之后继续给 tlp 进行转义。

html
<body>
  <table class="layui-hide" id="ID-table-demo-templet"></table>

  <script type="text/html" id="ID-table-demo-templet-user">
    <!-- jinja2 与 layui 的模版语法冲突-->
    <a href="" target="_blank">{{ '{{= d.username }}'|safe }}</a>
  </script>

  <script type="text/html" id="ID-table-demo-templet-switch">
    <!-- 这里的 checked 的状态值判断仅作为演示 -->
    <input type="checkbox" name="status"
           value="{{ '{{= d.id }}'|safe }}"
           title="热|"
           lay-skin="switch"
           lay-filter="demo-templet-status" {{ '{{= d.id == 10001 ? "checked" : "" }}' }}>
  </script>

  <script type="text/html" id="ID-table-demo-templet-other">
    <span class="layui-badge-rim" style="margin-right: 10px;"
      >评分:{{ '{{= d.score }}'|safe }}</span
    >
    <span class="layui-badge-rim">职业:{{ '{{= d.classify }}'| safe }}</span>
    <!--
        <span class="layui-badge-rim">下标:{{ '{{= d.LAY_INDEX }}'|safe }}</span>
        <span class="layui-badge-rim">序号:{{ '{{= d.LAY_NUM }}'|safe }}</span>
    -->
  </script>
  <script src="/static/layui.js"></script>
  <script>
    layui.use(function() {
      var table = layui.table;
      var form = layui.form;

      // 创建渲染实例
      table.render({
        elem: '#ID-table-demo-templet',
        url: '/static/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
        page: true,
        height: '315px',
        cols: [
          [
            {type: 'checkbox', fixed: 'left'},
            // 未自定义模板的普通列
            {field: 'id', fixed: 'left', width: 80, title: 'ID', sort: true},
            // 模板 - 选择器写法
            {field: 'username', width: 80, title: '用户', templet: '#ID-table-demo-templet-user'},
            // 模板 - 函数写法
            {
              field: 'sex', width: 60, title: '性别', templet: function(d) {
                if (d.sex === '男') {
                  return '<span style="color: blue">♂</span>';
                } else {
                  return '<span style="color: pink">♀</span>';
                }
              },
            },
            // 模板 - 普通字符写法
            {
              field: 'city',
              width: 115,
              title: '城市',
              templet: '<div><i class="layui-icon layui-icon-location"></i> {{ '{{= d.city }}'|safe }}</div>',
            },
            // 模板中可包含任意字段、任意内容(如表单等)
            {title: '状态', width: 85, templet: '#ID-table-demo-templet-switch'},
            {title: '其他', minWidth: 200, templet: '#ID-table-demo-templet-other'},
          ]],
      });

      // 状态 - 开关操作
      form.on('switch(demo-templet-status)', function(obj) {
        var id = this.value;
        var name = this.name;
        layer.tips(id + ' ' + name + ': ' + obj.elem.checked, obj.othis);
      });
    });
  </script>
</body>
json
{
  "code": 0,
  "msg": "",
  "count": 1000,
  "data": [
    {
      "id": 10000,
      "username": "user-0",
      "sex": "女",
      "city": "城市-0",
      "sign": "签名-0",
      "experience": 255,
      "logins": 24,
      "words": 82830700,
      "classify": "作家",
      "score": 57
    },
    {
      "id": 10001,
      "username": "user-1",
      "sex": "男",
      "city": "城市-1",
      "sign": "签名-1",
      "experience": 884,
      "logins": 58,
      "words": 64928690,
      "classify": "词人",
      "score": 70.5
    },
    {
      "id": 10002,
      "username": "user-2",
      "sex": "女",
      "city": "城市-2",
      "sign": "签名-2",
      "experience": 650,
      "logins": 77,
      "words": 6298078,
      "classify": "酱油",
      "score": 31
    },
    {
      "id": 10003,
      "username": "user-3",
      "sex": "女",
      "city": "城市-3",
      "sign": "签名-3",
      "experience": 362,
      "logins": 157,
      "words": 37117017,
      "classify": "诗人",
      "score": 68
    },
    {
      "id": 10004,
      "username": "user-4",
      "sex": "男",
      "city": "城市-4",
      "sign": "签名-4",
      "experience": 807,
      "logins": 51,
      "words": 76263262,
      "classify": "作家",
      "score": 6
    },
    {
      "id": 10005,
      "username": "user-5",
      "sex": "女",
      "city": "城市-5",
      "sign": "签名-5",
      "experience": 173,
      "logins": 68,
      "words": 60344147,
      "classify": "作家",
      "score": 87
    },
    {
      "id": 10006,
      "username": "user-6",
      "sex": "女",
      "city": "城市-6",
      "sign": "签名-6",
      "experience": 982,
      "logins": 37,
      "words": 57768166,
      "classify": "作家",
      "score": 34
    },
    {
      "id": 10007,
      "username": "user-7",
      "sex": "男",
      "city": "城市-7",
      "sign": "签名-7",
      "experience": 727,
      "logins": 150,
      "words": 82030578,
      "classify": "作家",
      "score": 28
    },
    {
      "id": 10008,
      "username": "user-8",
      "sex": "男",
      "city": "城市-8",
      "sign": "签名-8",
      "experience": 951,
      "logins": 133,
      "words": 16503371,
      "classify": "词人",
      "score": 14
    },
    {
      "id": 10009,
      "username": "user-9",
      "sex": "女",
      "city": "城市-9",
      "sign": "签名-9",
      "experience": 484,
      "logins": 25,
      "words": 86801934,
      "classify": "词人",
      "score": 75
    }
  ]
}

自定义样式

html
<style>
  /* 自定义样式  */
  .layui-table-testcss .layui-table-header,
  .layui-table-testcss thead tr {
    background-color: #f8fcf9;
    color: #16baaa;
  }

  .layui-form-testcss > div {
    margin-bottom: 6px;
  }
</style>
html
<div style="padding: 16px;">
  <table class="layui-hide" id="ID-table-demo-css"></table>
</div>
<script type="text/html" id="ID-table-demo-css-user">
  <ul>
    <li><strong>ID:</strong> {{ '{{= d.id }}'| safe }}</li>
    <li><strong>用户:</strong> {{ '{{= d.username }}'| safe }}</li>
    <li><strong>性别:</strong> {{ '{{= d.sex }}'| safe }}</li>
    <li><strong>城市:</strong> {{ '{{= d.city }}'| safe }}</li>
  </ul>
</script>
<script type="text/html" id="ID-table-demo-css-tool">
  <div class="layui-form layui-form-testcss">
      <div class="layui-input-wrap">
          <input name="AAA" value="{{ '{{= d.AAA || "" }}'| safe }}" lay-affix="clear" placeholder="表单 1"
                 class="layui-input">
      </div>
      <div class="layui-input-wrap">
          <input name="BBB" value="{{ '{{= d.BBB || "" }}'| safe }}" lay-affix="clear" placeholder="表单 2"
                 class="layui-input">
      </div>
      <div>
          <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="demo-css-submit">确认</button>
      </div>
  </div>
</script>
<script src="/static/layui.js"></script>
html
<script>
  layui.use(function () {
    var table = layui.table;
    var form = layui.form;

    // 创建渲染实例
    table.render({
      elem: "#ID-table-demo-css",
      url: "/static/demo1.json", // 此处为静态模拟数据,实际使用时需换成真实接口
      page: true,
      height: "full-35",
      lineStyle: "height: 151px;", // 定义表格的多行样式
      css: [
        // 直接给当前表格主容器重置 css 样式
        ".layui-table-page{text-align: center;}", // 让分页栏居中
      ].join(""),
      className: "layui-table-testcss", // 用于给表格主容器追加 css 类名
      cols: [
        [
          {
            field: "username",
            width: 160,
            title: "用户",
            templet: "#ID-table-demo-css-user",
          },
          // 设置单元格样式
          {
            field: "sign",
            minWidth: 100,
            title: "签名",
            style: "color: #000;",
          },
          { width: 160, title: "操作", templet: "#ID-table-demo-css-tool" },
        ],
      ],
    });
    // 表单提交
    form.on("submit(demo-css-submit)", function (data) {
      var field = data.field; // 获取表单字段值
      // 显示填写结果,仅作演示用
      layer.alert(JSON.stringify(field), {
        title: "当前填写的字段值",
      });
      // 此处可执行 Ajax 等操作
      // …
      return false; // 阻止默认 form 跳转
    });
  });
</script>
json
{
  "code": 0,
  "msg": "",
  "count": 1000,
  "totalRow": {
    "era": {
      "tang": "2",
      "song": "2",
      "xian": "20"
    }
  },
  "data": [
    {
      "id": "10001",
      "username": "李白",
      "email": "test1@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "君不见,黄河之水天上来,奔流到海不复回。 君不见,高堂明镜悲白发,朝如青丝暮成雪。 人生得意须尽欢,莫使金樽空对月。 天生我材必有用,千金散尽还复来。 烹羊宰牛且为乐,会须一饮三百杯。 岑夫子,丹丘生,将进酒,杯莫停。 与君歌一曲,请君为我倾耳听。(倾耳听 一作:侧耳听) 钟鼓馔玉不足贵,但愿长醉不复醒。(不足贵 一作:何足贵;不复醒 一作:不愿醒/不用醒) 古来圣贤皆寂寞,惟有饮者留其名。(古来 一作:自古;惟 通:唯) 陈王昔时宴平乐,斗酒十千恣欢谑。 主人何为言少钱,径须沽取对君酌。 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。",
      "experience": "12",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10002",
      "username": "杜甫",
      "email": "test2@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "舍南舍北皆春水,但见群鸥日日来。花径不曾缘客扫,蓬门今始为君开。盘飧市远无兼味,樽酒家贫只旧醅。肯与邻翁相对饮,隔篱呼取尽余杯。",
      "experience": "116",
      "ip": "192.168.0.8",
      "checkin": "108",
      "joinTime": "2016-10-14",
      "LAY_CHECKED": true
    },
    {
      "id": "10003",
      "username": "苏轼",
      "email": "test3@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。人生如梦,一尊还酹江月。",
      "experience": "65",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10004",
      "username": "李清照",
      "email": "test4@email.com",
      "sex": "女",
      "city": "浙江杭州",
      "sign": "昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否,知否?应是绿肥红瘦。",
      "experience": "777",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10005",
      "username": "冰心",
      "email": "test5@email.com",
      "sex": "女",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "86",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10006",
      "username": "张三",
      "email": "test6@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "12",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10007",
      "username": "张三7",
      "email": "test7@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "16",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10008",
      "username": "张三8",
      "email": "test8@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10009",
      "username": "张三9",
      "email": "test9@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10010",
      "username": "张三10",
      "email": "test10@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10011",
      "username": "张三11",
      "email": "test11@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10012",
      "username": "张三12",
      "email": "test12@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10013",
      "username": "张三13",
      "email": "test13@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10014",
      "username": "张三14",
      "email": "test14@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10015",
      "username": "张三15",
      "email": "test15@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10016",
      "username": "张三16",
      "email": "test16@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10017",
      "username": "张三17",
      "email": "test17@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10018",
      "username": "张三18",
      "email": "test18@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10019",
      "username": "张三19",
      "email": "test19@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10020",
      "username": "张三20",
      "email": "test20@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10021",
      "username": "张三21",
      "email": "test21@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10022",
      "username": "张三22",
      "email": "test22@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10023",
      "username": "张三23",
      "email": "test23@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    },
    {
      "id": "10024",
      "username": "张三24",
      "email": "test24@email.com",
      "sex": "男",
      "city": "浙江杭州",
      "sign": "保持真善美,温和待人",
      "experience": "106",
      "ip": "192.168.0.8",
      "checkin": "106",
      "joinTime": "2016-10-14"
    }
  ]
}

远程搜索

html
<form class="layui-form layui-row layui-col-space16">
  <div class="layui-col-md4">
    <div class="layui-input-wrap">
      <div class="layui-input-prefix">
        <i class="layui-icon layui-icon-username"></i>
      </div>
      <input
        type="text"
        name="A"
        value=""
        placeholder="Field A"
        class="layui-input"
        lay-affix="clear"
      />
    </div>
  </div>
  <div class="layui-col-md4">
    <div class="layui-input-wrap">
      <input
        type="text"
        name="B"
        placeholder="Field B"
        lay-affix="clear"
        class="layui-input"
      />
    </div>
  </div>
  <div class="layui-col-md4">
    <div class="layui-input-wrap">
      <div class="layui-input-prefix">
        <i class="layui-icon layui-icon-date"></i>
      </div>
      <input
        type="text"
        name="C"
        readonly
        placeholder="Field C"
        class="layui-input demo-table-search-date"
      />
    </div>
  </div>
  <div class="layui-btn-container layui-col-xs12">
    <button class="layui-btn" lay-submit lay-filter="demo-table-search">
      Search
    </button>
    <button type="reset" class="layui-btn layui-btn-primary">Clear</button>
  </div>
</form>

<table class="layui-hide" id="ID-table-demo-search"></table>
html
<script src="/static/layui.js"></script>
<script>
  layui.use(function () {
    var table = layui.table;
    var form = layui.form;
    var laydate = layui.laydate;
    // 创建表格实例
    table.render({
      elem: "#ID-table-demo-search",
      url: "/static/user.json", // 此处为静态模拟数据,实际使用时需换成真实接口
      cols: [
        [
          { checkbox: true, fixed: true },
          { field: "id", title: "ID", width: 80, sort: true, fixed: true },
          { field: "username", title: "用户名", width: 80 },
          { field: "sex", title: "性别", width: 80, sort: true },
          { field: "city", title: "城市", width: 80 },
          { field: "sign", title: "签名" },
          { field: "experience", title: "积分", sort: true, width: 80 },
        ],
      ],
      page: true,
      height: 310,
    });
    // 日期
    laydate.render({
      elem: ".demo-table-search-date",
    });
    // 搜索提交
    form.on("submit(demo-table-search)", function (data) {
      var field = data.field; // 获得表单字段
      // 执行搜索重载
      table.reload("ID-table-demo-search", {
        page: {
          curr: 1, // 重新从第 1 页开始
        },
        where: field, // 搜索的字段
      });
      layer.msg("搜索成功<br>此处为静态模拟数据,实际使用时换成真实接口即可");
      return false; // 阻止默认 form 跳转
    });
  });
</script>

权限控制编辑

html
<body>
  <table class="layui-hide" id="ID-table-demo-editable"></table>

  <script src="/static/layui.js"></script>
  <script>
    layui.use(function () {
      var table = layui.table;
      var util = layui.util;
      // 根据返回数据中某个字段来判断开启该行的编辑
      var editable = function (d) {
        if (d.editable) return "text"; // 这里假设以 editable 字段为判断依据
      };
      // 创建表格实例
      table.render({
        elem: "#ID-table-demo-editable",
        url: "/static/edit.json", // 此处为静态模拟数据,实际使用时需换成真实接口
        page: true,
        //,editTrigger: 'dblclick' // 触发编辑的事件类型(默认 click )。 v2.7.0 新增,之前版本固定为单击触发
        css: [
          // 对开启了编辑的单元格追加样式
          ".layui-table-view td[data-edit]{color: #16B777;}",
        ].join(""),
        cols: [
          [
            { checkbox: true, fixed: true },
            { field: "id", title: "ID", width: 80, sort: true, fixed: true },
            { field: "username", title: "用户名", width: 80, edit: editable },
            {
              field: "sex",
              title: "性别",
              width: 80,
              sort: true,
              edit: editable,
            },
            { field: "city", title: "城市", width: 80, edit: editable },
            { field: "sign", title: "签名", edit: editable },
            {
              field: "experience",
              title: "积分",
              sort: true,
              width: 80,
              edit: editable,
            },
          ],
        ],
        height: 310,
      });
      // 单元格编辑后的事件
      table.on("edit(ID-table-demo-editable)", function (obj) {
        var field = obj.field; // 得到修改的字段
        var value = obj.value; // 得到修改后的值
        var oldValue = obj.oldValue; // 得到修改前的值 -- v2.8.0 新增
        var data = obj.data; // 得到所在行所有键值
        var col = obj.getCol(); // 得到当前列的表头配置属性 -- v2.8.0 新增

        // 值的校验
        if (value.replace(/\s/g, "") === "") {
          layer.tips("值不能为空", this, { tips: 1 });
          return obj.reedit(); // 重新编辑 -- v2.8.0 新增
        }
        // 编辑后续操作,如提交更新请求,以完成真实的数据更新
        // …

        // 显示 - 仅用于演示
        layer.msg(
          "[ID: " +
            data.id +
            "] " +
            field +
            " 字段更改值为:" +
            util.escape(value),
        );
      });
    });
  </script>
</body>
json
{
  "code": 0,
  "msg": "",
  "count": 1000,
  "data": [
    {
      "id": 10000,
      "username": "user-0",
      "sex": "女",
      "city": "城市-0",
      "sign": "签名-0",
      "experience": 255,
      "logins": 24,
      "words": 82830700,
      "classify": "作家",
      "score": 57
    },
    {
      "id": 10001,
      "username": "user-1",
      "sex": "男",
      "city": "城市-1",
      "sign": "签名-1",
      "experience": 884,
      "logins": 58,
      "words": 64928690,
      "classify": "词人",
      "score": 70.5,
      "editable": true
    },
    {
      "id": 10002,
      "username": "user-2",
      "sex": "女",
      "city": "城市-2",
      "sign": "签名-2",
      "experience": 650,
      "logins": 77,
      "words": 6298078,
      "classify": "酱油",
      "score": 31
    },
    {
      "id": 10003,
      "username": "user-3",
      "sex": "女",
      "city": "城市-3",
      "sign": "签名-3",
      "experience": 362,
      "logins": 157,
      "words": 37117017,
      "classify": "诗人",
      "score": 68,
      "editable": true
    },
    {
      "id": 10004,
      "username": "user-4",
      "sex": "男",
      "city": "城市-4",
      "sign": "签名-4",
      "experience": 807,
      "logins": 51,
      "words": 76263262,
      "classify": "作家",
      "score": 6
    },
    {
      "id": 10005,
      "username": "user-5",
      "sex": "女",
      "city": "城市-5",
      "sign": "签名-5",
      "experience": 173,
      "logins": 68,
      "words": 60344147,
      "classify": "作家",
      "score": 87,
      "editable": true
    },
    {
      "id": 10006,
      "username": "user-6",
      "sex": "女",
      "city": "城市-6",
      "sign": "签名-6",
      "experience": 982,
      "logins": 37,
      "words": 57768166,
      "classify": "作家",
      "score": 34,
      "editable": true
    },
    {
      "id": 10007,
      "username": "user-7",
      "sex": "男",
      "city": "城市-7",
      "sign": "签名-7",
      "experience": 727,
      "logins": 150,
      "words": 82030578,
      "classify": "作家",
      "score": 28,
      "editable": true
    },
    {
      "id": 10008,
      "username": "user-8",
      "sex": "男",
      "city": "城市-8",
      "sign": "签名-8",
      "experience": 951,
      "logins": 133,
      "words": 16503371,
      "classify": "词人",
      "score": 14,
      "editable": true
    },
    {
      "id": 10009,
      "username": "user-9",
      "sex": "女",
      "city": "城市-9",
      "sign": "签名-9",
      "experience": 484,
      "logins": 25,
      "words": 86801934,
      "classify": "词人",
      "score": 75
    }
  ]
}

多样化编辑

html
<table class="layui-hide" id="ID-table-demo-editmodes"></table>

<script type="text/html" id="TPL-select-primary">
    {{ '{{#  var cityList = d.cityList || ["北京","上海","广州","城市-1"]; }}'|safe }}
    <select name="city" class="layui-border select-demo-primary" lay-ignore>
        <option value="">原生 select 框</option>
        {{ '{{#  layui.each(cityList, function(i, v){ }}'|safe }}
        <option value="{{ '{{= v }}'|safe }}" {{ "{{= v === d.city ? 'selected' : '' }}"|safe }}>{{ '{{= v }}'|safe }}</option>
        {{ '{{#  }); }}'|safe }}
    </select>
</script>

<!-- layui select 在 table 中使用(不推荐。因为当 select 出现在 table 底部时,可能会撑起多余高度) -->
<script type="text/html" id="TPL-select-city">
    {{ '{{#  var cityList = d.cityList || ["北京","上海","广州","城市-1"]; }}'|safe }}
    <select name="city" lay-filter="select-demo">
        <option value="">select 方式</option>
        {{ '{{#  layui.each(cityList, function(i, v){ }}'|safe }}
        <option value="{{ '{{= v }}'|safe }}" {{ "{{= v === d.city ? 'selected' : '' }}"|safe }}>{{ '{{= v }}'|safe }}</option>
        {{ '{{#  }); }}'|safe }}
    </select>
</script>

<!-- 推荐 -->
<script type="text/html" id="TPL-dropdpwn-demo">
    <button class="layui-btn layui-btn-primary dropdpwn-demo">
        <span>{{ "{{= d.sex || '保密' }}"|safe }}</span>
        <i class="layui-icon layui-icon-down layui-font-12"></i>
    </button>
</script>

<!-- laydate -->
<script type="text/html" id="TPL-laydate-demo">
    <input class="layui-input laydate-demo" placeholder="选择日期" value="{{ '{{= d.fieldname3 || "" }}'|safe }}">
</script>

<!-- colorpicker -->
<script type="text/html" id="TPL-colorpicker-demo">
    {{ "{{#  var color = d.color || ['#16baaa','#16b777','#1E9FFF','#FF5722','#FFB800','#393D49'][Math.round(Math.random()*5)]; }}"|safe }}
    <div class="colorpicker-demo" lay-options="{color: '{{ '{{= color }}' }}'}"></div>
</script>
html
<script src="/static/layui.js"></script>
<script>
  layui.use(function () {
    var $ = layui.$;
    var table = layui.table;
    var form = layui.form;
    var dropdown = layui.dropdown;
    var laydate = layui.laydate;
    var colorpicker = layui.colorpicker;

    // 渲染
    table.render({
      elem: "#ID-table-demo-editmodes",
      url: "/static/user.json", // 此处为静态模拟数据,实际使用时需换成真实接口
      page: true,
      css: [
        // 设置单元格样式
        // 取消默认的溢出隐藏,并设置适当高度
        ".layui-table-cell{height: 50px; line-height: 40px; overflow: visible;}",
        ".layui-table-cell .layui-colorpicker{width: 38px; height: 38px;}",
        ".layui-table-cell select{height: 36px; padding: 0 5px;}",
      ].join(""),
      cols: [
        [
          // 表头
          {
            field: "id",
            title: "ID",
            width: 80,
            align: "center",
            fixed: "left",
          },
          {
            field: "city",
            title: "原生 select",
            width: 150,
            templet: "#TPL-select-primary",
          },
          //{field: 'city', title: 'layui select', width:150, templet: '#TPL-select-city'},
          {
            field: "sex",
            title: "dropdown",
            width: 115,
            align: "center",
            templet: "#TPL-dropdpwn-demo",
          },
          {
            field: "date",
            title: "laydate",
            width: 150,
            templet: "#TPL-laydate-demo",
          },
          {
            field: "color",
            title: "colorpicker",
            width: 100,
            align: "center",
            templet: "#TPL-colorpicker-demo",
          },
          { field: "sign", title: "文本", edit: "textarea" },
        ],
      ],
      done: function (res, curr, count) {
        var options = this;

        // 获取当前行数据
        table.getRowData = function (elem) {
          var index = $(elem).closest("tr").data("index");
          return table.cache[options.id][index] || {};
        };

        // 原生 select 事件
        $(".select-demo-primary").on("change", function () {
          var value = this.value; // 获取选中项 value
          var data = table.getRowData(this); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
          // 更新数据中对应的字段
          data.city = value;
          // 显示 - 仅用于演示
          layer.msg(
            "选中值: " + value + "<br>当前行数据:" + JSON.stringify(data),
          );
        });

        // layui form select 事件
        form.on("select(select-demo)", function (obj) {
          console.log(obj); // 获取选中项数据

          // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
          var data = table.getRowData(obj.elem);
          // 更新数据中对应的字段
          data.city = value;
          console.log(data);
        });

        // dropdown 方式的下拉选择
        dropdown.render({
          elem: ".dropdpwn-demo",
          // trigger: 'hover',
          // 此处的 data 值,可根据 done 返回的 res 遍历来赋值
          data: [
            {
              title: "男",
              id: 100,
            },
            {
              title: "女",
              id: 101,
            },
            {
              title: "保密",
              id: 102,
            },
          ],
          click: function (obj) {
            var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)

            this.elem.find("span").html(obj.title);
            // 更新数据中对应的字段
            data.sex = obj.title;
            // 显示 - 仅用于演示
            layer.msg(
              "选中值: " +
                obj.title +
                "<br>当前行数据:" +
                JSON.stringify(data),
            );
          },
        });

        // laydate
        laydate.render({
          elem: ".laydate-demo",
          done: function (value, date, endDate) {
            var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
            // 更新数据中对应的字段
            data.date = value;

            // 显示 - 仅用于演示
            layer.msg(
              "选中值: " + value + "<br>当前行数据:" + JSON.stringify(data),
            );
          },
        });

        // colorpicker
        colorpicker.render({
          elem: ".colorpicker-demo",
          done: function (value) {
            var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
            // 更新数据中对应的字段
            data.color = value;

            // 显示 - 仅用于演示
            layer.msg(
              "选中值: " + value + "<br>当前行数据:" + JSON.stringify(data),
            );
          },
        });

        // 单元格普通编辑事件
        table.on("edit(ID-table-demo-editmodes)", function (obj) {
          var value = obj.value; // 得到修改后的值
          var data = obj.data; // 得到所在行所有键值
          var field = obj.field; // 得到字段

          // 更新数据中对应的字段
          var update = {};
          update[field] = value;
          obj.update(update);

          // 编辑后续操作,如提交更新请求,以完成真实的数据更新
          // …

          // 显示 - 仅用于演示
          layer.msg(
            "编辑值: " + value + "<br>当前行数据:" + JSON.stringify(data),
          );
        });

        // 更多编辑方式……
      },
    });
  });
</script>