Thymeleaf 模板引擎原理

发布于:2025-08-03 ⋅ 阅读:(12) ⋅ 点赞:(0)

Thymeleaf 的模板文件,本质上是标准的 HTML 文件,只是“加了标记( th:的属性”,让模板引擎在服务端渲染时能 识别并处理 这些属性,从而完成数据(model) 的填充。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>

<h1>用户注册</h1>

<!-- 注册表单 -->
<form action="#" th:action="@{/register}" th:object="${user}" method="post">
    <p>姓名: <input type="text" th:field="*{name}" /></p>
    <p>邮箱: <input type="email" th:field="*{email}" /></p>
    <p><input type="submit" value="提交"/></p>
</form>

<!-- 已注册用户列表 -->
<h2>已注册用户</h2>
<ul>
    <li th:if="${#lists.isEmpty(users)}">暂无用户</li>
    <li th:each="user : ${users}">
        [[${user.name}]] - [[${user.email}]]
    </li>
</ul>

</body>
</html>

 这个就是前后没有完全分离的项目,虽然画页面可以和前端分开做,但是页面的跳转还是靠后端的SpringMVC 的controller 实现控制的,页面的调试渲染数据还是需要后端返回model,这种强依赖性影响开发效率。于是后面出现一种架构  MVVM, 拆开就是  V(前端) <=== VM(页面数据代理) ===> M(后端)

也就是说前端要的模型数据直接找代理(vm)要,通过数据双向绑定自己模拟所需数据,不用直接找后端要,如果真要就发送Ajax请求到后端。基于这样的思想前端开源框架代表有 Vue 。加上组件模块化开发的思想,最终前后迎来分离项目的发展  。

下面这个demo 是没有使用Thymeleaf 写的html,并且静态资源还是在后台服务器上,属于纯静态资源展示。 

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>欢迎光临</title>
    </head>
    <body>
        <!-- 如果请求的是根目录(/)Spring Boot 会自动查找以下文件作为欢迎页:index.html 或 index.htm 或 index.jsp -->
        <div class="welcome-container">
            <h1>欢迎来到我们的网站!</h1>
            <p>探索我们为您精心准备的内容</p>

            <div class="image-gallery">
                <img src="/images/wandou.jpg" alt="Wandou Image"/>
            </div>
        </div>

        <!-- 样式写在 body 底部 -->
        <style>
            /* 重置默认样式 */
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            body {
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
                min-height: 100vh;
                display: flex;
                justify-content: center;
                align-items: center;
                padding: 20px;
                color: #333;
            }

            .welcome-container {
                text-align: center;
                background: white;
                padding: 30px 20px;
                border-radius: 16px;
                box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
                max-width: 90%;
                width: 100%;
                max-width: 800px;
            }

            h1 {
                font-size: 2.2rem;
                color: #2c3e50;
                margin-bottom: 12px;
            }

            p {
                font-size: 1.2rem;
                color: #7f8c8d;
                margin-bottom: 24px;
            }

            .image-gallery {
                display: flex;
                flex-wrap: wrap;
                justify-content: center;
                gap: 16px;
                margin-top: 20px;
            }

            .image-gallery img {
                width: 100%;
                max-width: 300px; /* 限制最大宽度 */
                height: auto;
                border-radius: 12px;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
                transition: transform 0.3s ease;
            }

            .image-gallery img:hover {
                transform: translateY(-5px);
            }

            /* 小屏幕优化 */
            @media (max-width: 600px) {
                h1 {
                    font-size: 1.8rem;
                }
                p {
                    font-size: 1rem;
                }
                .welcome-container {
                    padding: 20px 15px;
                }
            }

            /* 平板适配 */
            @media (min-width: 601px) and (max-width: 1024px) {
                .image-gallery {
                    gap: 20px;
                }
            }
        </style>
    </body>
</html>

 直接访问ip和端口

  


网站公告

今日签到

点亮在社区的每一天
去签到