Skip to content

9 局部变量

Thymeleaf 中的局部变量(Local Variables) 是指为模板中「特定片段」定义的变量,仅在该片段范围内可被访问和求值,不会污染全局上下文。

我们之前接触过的遍历变量(如产品列表中的 prod)就是典型的局部变量:

html
<tr th:each="prod : ${prods}">
    <!-- 仅在当前 <tr> 标签及其子元素内,prod 变量可访问 -->
    <td th:text="${prod.name}">Onions</td>
</tr>
  • 作用域:仅在定义变量的标签(如上例 <tr>)及其所有子元素内有效;
  • 执行顺序:对于同一标签上的多个 th:* 属性,局部变量会在定义它的属性(如 th:each)执行后,才对其他属性可见(即优先级低于定义属性);
  • 上下文隔离:局部变量会被添加到上下文变量映射中,但仅在作用域内生效,外部无法访问。

除了 th:each 自动生成遍历变量,Thymeleaf 还提供 th:with 属性,专门用于手动声明局部变量(无需遍历),语法类似“变量赋值”:

html
<!-- 声明局部变量 firstPer,值为 persons 列表第一个元素 -->
<div th:with="firstPer=${persons[0]}">
  <p>
    The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
  </p>
</div>

th:with 处理后,firstPer 会作为局部变量添加到上下文,仅在 <div> 标签范围内可用;超出 <div> 后,firstPer 变量立即失效。

th:with 支持用逗号分隔,一次性声明多个局部变量:

html
<div th:with="firstPer=${persons[0]},secondPer=${persons[1]}">
  <p>
    The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
  </p>
  <p>
    But the name of the second person is 
    <span th:text="${secondPer.name}">Marcus Antonius</span>.
  </p>
</div>

th:with 允许在同一属性中复用已定义的局部变量,按声明顺序求值:

html
<!-- 先定义 company,再用 company 定义 account -->
<div th:with="company=${user.company + ' Co.'},account=${accounts[company]}">
  <!-- 可访问 company 和 account 变量 -->
</div>

让我们在杂货铺首页中使用它吧,还记得之前学的格式化日期的代码吗?

html
<p>
    Today is:
    <span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 february 2011</span>
</p>

如果我们想要根据语言来格式化日期怎么办?首先,配置国际化属性文件

  • home_en.propertiesdate.format=MMMM dd'','' yyyy(英文格式:February 13, 2011)
  • home_es.propertiesdate.format=dd ''de'' MMMM'','' yyyy(西语格式:13 de February, 2011)

用 th:with 声明日期格式变量,然后在 th:text 表达式中使用:

html
<!-- 方式1:在父标签声明变量,子标签使用 -->
<p th:with="df=#{date.format}">
  Today is: <span th:text="${#calendars.format(today,df)}">13 February 2011</span>
</p>

这代码看起来就干净简单多了。事实上,th:with 的执行优先级高于 th:text 属性,所以我们可以直接在<span>标签中声明所有属性

html
<!-- 方式2:直接在使用标签声明(利用优先级,th:with 先执行) -->
<p>
  Today is: 
  <span th:with="df=#{date.format}" 
        th:text="${#calendars.format(today,df)}">13 February 2011</span>
</p>

你可能会疑惑,执行优先级是什么?我们还没谈到过这个呢!别担心,这正是下一章要讲的内容。

关键注意事项

  • 优先级th:with 的执行优先级高于 th:text/th:href 等属性,因此在同一标签内,th:with 定义的变量可直接被其他属性使用;
  • 作用域边界:局部变量仅在包含 th:with/th:each 的标签及其子元素内有效,超出则无法访问;
  • 上下文叠加:局部变量不会覆盖全局变量,而是叠加到上下文映射中——若局部变量名与全局变量名冲突,局部变量优先级更高(仅在作用域内)。

总结

  1. 局部变量是模板特定片段的专属变量,仅在作用域内有效,核心来源有两个:th:each 遍历生成、th:with 手动声明;
  2. th:with 支持多变量声明、变量复用,可简化复杂表达式,提升模板可读性;
  3. 局部变量叠加在全局上下文上,作用域为声明标签及其子元素,优先级高于同名称的全局变量(仅在作用域内)。