深色模式
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.properties:date.format=MMMM dd'','' yyyy(英文格式:February 13, 2011)home_es.properties:date.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的标签及其子元素内有效,超出则无法访问; - 上下文叠加:局部变量不会覆盖全局变量,而是叠加到上下文映射中——若局部变量名与全局变量名冲突,局部变量优先级更高(仅在作用域内)。
总结
- 局部变量是模板特定片段的专属变量,仅在作用域内有效,核心来源有两个:
th:each遍历生成、th:with手动声明; th:with支持多变量声明、变量复用,可简化复杂表达式,提升模板可读性;- 局部变量叠加在全局上下文上,作用域为声明标签及其子元素,优先级高于同名称的全局变量(仅在作用域内)。
