thymeleaf中使用layui(公用部分提?。?/h2>

layui已經(jīng)提供了一整套的UI布局及相關(guān)組件,并且有相當(dāng)完善的api文檔,本文重點(diǎn)在于thymeleaf中如何使用layui,包括公用部分的提取,而非簡(jiǎn)單的layui的用法。

先上兩個(gè)效果圖

列表.png

表單.png

一、思路

1.像傳統(tǒng)的一樣建文件頭和尾(但是又和傳統(tǒng)的寫法不同,見下面代碼)
2.定義公用js--common.js
3.定義公用css--用來重寫一些樣式或者自定義樣式
4.編寫列表頁(yè)
5.編寫表單頁(yè)

二、文件頭和尾

頭部引入css,尾部引入js,定義兩個(gè)模板(一個(gè)也可以,里面的碎片分開寫,我喜歡寫兩個(gè)分別引入),注意th:fragment,fragment即碎片,可以在模板任何位置引入,此處為分別定義名為header和js_footer的碎片,以供后面引用

樣式文件 link.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<div th:fragment="header">
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"/>
    <link rel="stylesheet" th:href="@{/js/layui/css/layui.css}"/>
    <link rel="stylesheet" th:href="@{/css/common.css}"/>
</div>
</html>
js文件 script.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<div th:fragment="js_footer">
    <script th:src="@{/js/layui/layui.all.js}"></script>
    <script th:src="@{/js/common/common.js}"></script>
    <!-- 讓IE8/9支持媒體查詢,從而兼容柵格 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</div>
<script>
    var basePath='http://www.baidu.com';
</script>
</html>

三、公用js

該文件包含幾個(gè)方法:
1.initTable 初始化帶分頁(yè)的table,注意其中的request屬性,可以配置和你后臺(tái)Page對(duì)象對(duì)應(yīng)的屬性,具體可以參考layui官方文檔
2.searchTable table的搜索功能,調(diào)用layui table模塊的的重載功能,參數(shù)組建思路:獲取序列化的表單,組裝成json對(duì)象
3.upload 文件上傳
4.openFrame 打開彈出層,基于最頂層彈出

var Common = function () {
    var initTable = function (ele, url, cols, table, doneCallBack) {
        return table.render({
            elem: ele
            , url: url
            , method: 'POST'
            , cellMinWidth: 80 //全局定義常規(guī)單元格的最小寬度,layui 2.2.1 新增
            , cols: cols
            , page: {
                limits: [10, 20, 50, 100]
            },
            request: {
                pageName: 'current',
                limitName: 'size'
            },
            done: function (res, curr, count) {
                if (typeof(doneCallBack) === "function") {
                    doneCallBack(res);
                }
            }
        });
    };

    var searchTable = function (formId, tableIns) {
        var queryParams = getParams(formId);
        tableIns.reload({
            where: {condition: queryParams},
            page: {
                curr: 1 //重新從第 1 頁(yè)開始
            }
        });
    };

    var getParams = function (formId) {
        var $ = layui.jquery;
        var _params = {};
        $.each($('#' + formId).serializeArray(), function (i, field) {
            if (null != field.value && "" != field.value) {
                _params[field.name] = field.value;
            }
        });
        return _params;
    };

    var upload = function (eleId, layUpload, done, error, accept, exts) {
        layUpload.render({
            elem: eleId //綁定元素
            , url: '/upload/' //上傳接口
            , accept: accept === undefined ? 'file' : accept
            , exts: exts === undefined ? 'jpg|png|gif|bmp|jpeg' : exts
            , done: function (res) {
                //上傳完畢回調(diào)
                if (typeof (done) === 'function') {
                    done(res)
                }
            }
            , error: function () {
                //請(qǐng)求異?;卣{(diào)
                if (typeof (error) === 'function') {
                    error()
                }
            }
        });
    };

    var openFrame = function (url, title, width, height) {
        width = width === undefined ? '900px' : width;
        height = height === undefined ? '500px' : height;
        return top.layer.open({
            area: [width, height],
            type: 2,
            title: title,
            content: url //這里content是一個(gè)URL,如果你不想讓iframe出現(xiàn)滾動(dòng)條,你還可以content: ['http://sentsin.com', 'no']
        });
    };
    return {
        initTable: function (ele, url, cols, table, doneCallBack) {
            return initTable(ele, url, cols, table, doneCallBack);
        },
        searchTable: function (formId, table) {
            searchTable(formId, table);
        },
        uploadFile: function (eleId, layUpload, done, error, accept, exts) {
            upload(eleId, layUpload, done, error, accept, exts);
        },
        openFrame: function (url, title, width, height) {
            return openFrame(url, title, width, height);
        }
    }
}();

四、公用css

這個(gè)可以根據(jù)個(gè)人喜好或者項(xiàng)目實(shí)際情況自己定義

.form-body{
    margin-top: 4%
}
.layui-input-inline{
    width: 350px !important;
}

五、列表頁(yè)

整個(gè)html除了頭部的引入,整體分為三部分:
1.上面form為搜索內(nèi)容部分
2.中間一個(gè)table為主窗口
3.注意一個(gè)id="toolBars"的js,為工具條,用于追加在每一列的后面
4.可以看到下面頁(yè)面初始化等都調(diào)用了Common.js中的對(duì)應(yīng)方法

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Title</title>
    <div th:replace="common/links::header"></div>
    <div th:replace="common/script::js_footer"></div>
</head>
<body>
<fieldset class="layui-elem-field">
    <legend>條件搜索</legend>
<form class="layui-form" style="text-align: center" id="searchForm">
    <div class="layui-form-item">
        <div class="layui-inline">
            <label class="layui-form-label">手機(jī)號(hào)</label>
            <div class="layui-input-inline">
                <input type="tel" name="mobile"  autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-inline">
            <label class="layui-form-label">用戶名</label>
            <div class="layui-input-inline">
                <input type="text" name="username"  autocomplete="off" class="layui-input">
            </div>
        </div>
    </div>
    <div class="layui-form-item">
        <div class="layui-input-block">
            <button class="layui-btn" id="searchBtn" type="button">搜索</button>
            <button type="reset" class="layui-btn layui-btn-primary">重置</button>
            <button type="reset" class="layui-btn layui-btn-primary">新增</button>
        </div>
    </div>
</form>
</fieldset>
<hr class="layui-bg-green">
<table class="layui-hide" id="userTable" lay-filter="userFilter"></table>
<script type="text/html" id="toolBars">
    <a class="layui-btn layui-btn-xs" lay-event="detail">查看</a>
    <a class="layui-btn layui-btn-xs" lay-event="edit">編輯</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">刪除</a>

    <!-- 這里同樣支持 laytpl 語(yǔ)法,如: -->
    <a class="layui-btn layui-btn-xs" lay-event="check">審核</a>
</script>
<script>
    cols=[[
        {checkbox: true, fixed: true}
        ,{field:'username', title: '用戶名'} //width 支持:數(shù)字、百分比和不填寫。你還可以通過 minWidth 參數(shù)局部定義當(dāng)前單元格的最小寬度,layui 2.2.1 新增
        ,{field:'mobile', title: '手機(jī)號(hào)', sort: true}
        ,{field:'nickname', title: '昵稱'}
        ,{field:'lastLoginTime', title: '最后登錄時(shí)間'}
        ,{field:'ip', title: '最后登錄ip', align: 'center'} //單元格內(nèi)容水平居中
        ,{field:'op',title: '操作', align:'center', toolbar: '#toolBars'} //這里的toolbar值是模板元素的選擇器
    ]];

    layui.use('table', function(){
        var table = layui.table,$ = layui.jquery;
        table.on('tool(userFilter)', function(obj){
            var data = obj.data; //獲得當(dāng)前行數(shù)據(jù)
            var layEvent = obj.event; //獲得 lay-event 對(duì)應(yīng)的值(也可以是表頭的 event 參數(shù)對(duì)應(yīng)的值)
            if(layEvent === 'detail'){ //查看
                //TODO detail
            } else if(layEvent === 'del'){ //刪除
                top.layer.confirm('真的刪除行么', function(index){
                    //TODO do delete
                });
            } else if(layEvent === 'edit'){ //編輯
                Common.openFrame('/sys/user/to-edit?id=' + data.id,'修改用戶信息');
            }
        });
        var initTable = Common.initTable('#userTable','/sys/user/query-page',cols,table);
        $('#searchBtn').on('click',function () {
            Common.searchTable('searchForm',initTable);
        })
    });
</script>
</body>
</html>

六、表單頁(yè)

列表出來之后表單就更簡(jiǎn)單了,只需要去layui官網(wǎng)找個(gè)表單,根據(jù)自己的實(shí)際情況布局即可,特別說明的是校驗(yàn),即verify.js,用于自己對(duì)驗(yàn)證方法的擴(kuò)展
form.html

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Title</title>
    <div th:replace="common/links::header"></div>
    <div th:replace="common/script::js_footer"></div>
    <script th:src="@{/js/common/verify.js}"></script>
</head>
<body class="form-body">
<form class="layui-form " action="">
    <div class="layui-form-item layui-col-md6 layui-col-md-offset2">
            <label class="layui-form-label">用戶名</label>
            <div class="layui-input-inline form-length350">
                <input type="text" name="username" th:value="${user.username}" lay-verify="required|username" placeholder="請(qǐng)輸入用戶名" autocomplete="off" class="layui-input">
            </div>
            <div class="layui-form-mid layui-word-aux">*6-12個(gè)字符</div>
    </div>
    <div class="layui-form-item layui-col-md4 layui-col-md-offset2">
        <label class="layui-form-label">密碼框</label>
        <div class="layui-input-inline">
            <input type="password" name="password"  lay-verify="required|password" placeholder="請(qǐng)輸入密碼" autocomplete="off" class="layui-input">
        </div>
        <div class="layui-form-mid layui-word-aux">*包含a_z、A_Z、1-9中的兩種,且長(zhǎng)度6-20</div>
    </div>
    <div class="layui-form-item layui-col-md4 layui-col-md-offset2">
        <label class="layui-form-label">手機(jī)號(hào)</label>
        <div class="layui-input-inline">
            <input type="text" name="mobile"  th:value="${user.mobile}" lay-verify="required|phone" placeholder="請(qǐng)輸入手機(jī)號(hào)" autocomplete="off" class="layui-input">
        </div>
        <div class="layui-form-mid layui-word-aux">*手機(jī)號(hào)</div>
    </div>
    <div class="layui-form-item layui-col-md4 layui-col-md-offset2">
        <label class="layui-form-label">昵稱</label>
        <div class="layui-input-inline">
            <input type="text" name="nickname" th:value="${user.nickname}" lay-verify="required" placeholder="請(qǐng)輸入昵稱" autocomplete="off" class="layui-input">
        </div>
        <div class="layui-form-mid layui-word-aux">*不多于30個(gè)字符</div>
    </div>
    <div class="layui-form-item">
        <div class="layui-col-md4 layui-col-md-offset2">
        <label class="layui-form-label">頭像</label>
        <div class="layui-input-inline">
            <button type="button" class="layui-btn" id="test1">
                <i class="layui-icon">&#xe67c;</i>上傳圖片
            </button>
        </div>
        </div>
    </div>
    <div class="layui-form-item layui-col-md-offset4">
        <div class="layui-input-block">
            <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
            <button type="reset" class="layui-btn layui-btn-primary">重置</button>
        </div>
    </div>
</form>
<script>
    layui.use('form', function () {
        var form = layui.form, upload = layui.upload;
        form.render();
        Common.uploadFile('#test1', upload, function (data) {
            console.log(data);
        });
        //監(jiān)聽提交
        form.on('submit(formDemo)', function (data) {
            layer.msg(JSON.stringify(data.field));
            //TODO ajax提交表單
            return false;
        });
    });
</script>
</body>
</html>

verify.js

layui.use('form', function () {
    var form = layui.form;
    //自定義驗(yàn)證規(guī)則
    form.verify({
        username: function (value) {
            if (value.length < 6 || value.length > 12) {
                return '請(qǐng)輸入6到12位的用戶名';
            }
        }, password: function (value) {
            if (value.length < 4) {
                return '內(nèi)容請(qǐng)輸入至少4個(gè)字符';
            }
        }
        , phone: [/^1[3|4|5|7|8]\d{9}$/, '手機(jī)必須11位,只能是數(shù)字!']
        , email: [/^[a-z0-9._%-]+@([a-z0-9-]+\.)+[a-z]{2,4}$|^1[3|4|5|7|8]\d{9}$/, '郵箱格式不對(duì)']
    });
})

其他小技巧:
idea使用thymeleaf模板時(shí),頁(yè)面取值總提示無法解析變量,但是又不影響實(shí)際應(yīng)用,據(jù)說idea2017.3已經(jīng)解決了,但是我現(xiàn)在用的2017.2,沒有更新,但是同樣可以解決。錯(cuò)誤提示如圖


波浪線提示.png

解決方法也很簡(jiǎn)單:File--settings--Editor--Inspections--Thymeleaf,去掉第一個(gè)校驗(yàn)即可。


去掉波浪線提示.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 22年12月更新:個(gè)人網(wǎng)站關(guān)停,如果仍舊對(duì)舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,411評(píng)論 22 257
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 14,154評(píng)論 1 92
  • 1.幾種基本數(shù)據(jù)類型?復(fù)雜數(shù)據(jù)類型?值類型和引用數(shù)據(jù)類型?堆棧數(shù)據(jù)結(jié)構(gòu)? 基本數(shù)據(jù)類型:Undefined、Nul...
    伯納烏的追風(fēng)少年閱讀 26,137評(píng)論 2 46
  • 草兒低下了頭,天更藍(lán)了,云也就更慵懶了,昨天夜里聽著細(xì)雨敲打窗欞的聲音,曉得春天仍在流連忘返的走著、走著……時(shí)近暮...
    薩芬閱讀 285評(píng)論 0 0
  • 昨晚翻箱倒柜,又把這雙鞋翻出來,每年到這個(gè)時(shí)候她即將派上用場(chǎng)。年會(huì)專用,哈哈 年會(huì)走紅毯的時(shí)候戰(zhàn)鞋,現(xiàn)在不穿高跟鞋...
    幸福未央_Jojo閱讀 206評(píng)論 0 0

友情鏈接更多精彩內(nèi)容