整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Thymeleaf动态菜单渲染:程序员的进阶指南

在现代Web开发中,动态生成的菜单不仅能够提升用户体验,还能简化应用程序的维护工作。Thymeleaf作为一款流行的服务器端Java模板引擎,提供了丰富的标签和表达式语法,使得动态内容的生成变得简单而高效。本文将深入解析如何使用Thymeleaf来创建动态菜单,并通过代码示例来演示其实际应用。




一、Thymeleaf简介

Thymeleaf是一个用于Web和独立环境的现代服务器端Java模板引擎。它支持HTML、XML、JSF和Velocity模板,并且可以很好地与Spring框架集成。Thymeleaf的一大特点就是能够处理静态和动态内容,这意味着即使在没有后端数据的情况下,模板仍然能够正确显示。

二、动态菜单的实现原理

在Web应用中,动态菜单通常是从后端获取数据,然后在前端根据这些数据动态生成菜单结构。Thymeleaf通过其特有的语法,可以轻松地将后端数据绑定到HTML元素上,从而实现动态内容的填充。

三、代码示例

假设我们有一个简单的JavaBean代表菜单项:

public class MenuItem {
    private String name;
    private String url;
    private List<MenuItem> children;

    // 省略构造函数、getter和setter...
}

后端控制器将返回一个菜单列表:

@GetMapping("/menu")
public List<MenuItem> getMenuList() {
    // 假设这里从数据库或缓存中获取菜单数据
    return menuService.getAllMenus();
}

在Thymeleaf模板中,我们可以使用th:each和th:if标签来遍历菜单项,并根据条件渲染菜单结构:

<!-- index.html -->
<ul th:each="item : ${menuList}">
    <li>
        <a th:href="${item.url}" th:text="${item.name}"></a>
        <!-- 如果有子菜单,递归渲染 -->
        <ul th:if="${!#lists.isEmpty(item.children)}">
            <li th:each="child : ${item.children}">
                <a th:href="${child.url}" th:text="${child.name}"></a>
            </li>
        </ul>
    </li>
</ul>

四、源码解析

在上述代码中,th:each用于迭代menuList中的每一项,th:href和th:text分别用于设置链接的URL和显示的文本。当item.children不为空时,会进一步渲染子菜单。

五、优化技巧

  1. 性能优化:避免在模板中进行复杂的计算或数据库查询,这些应该在后端完成。
  2. 可读性:使用有意义的变量名和清晰的逻辑结构,提高模板的可读性和可维护性。
  3. 国际化:使用Thymeleaf的国际化支持,使菜单项名称能够根据用户语言偏好动态变化。

结语

通过本文的学习,你已经掌握了如何使用Thymeleaf来创建动态菜单的基本方法。动态菜单不仅能够提高Web应用的灵活性,还能显著提升用户体验。在实际项目中,可以根据具体需求进一步优化和扩展菜单功能,比如加入搜索、过滤和排序等功能,让菜单更加智能和人性化。

#头条创作挑战赛#

日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。

函数是 JavaScript 最重要的方面之一。本文将通过示例探索 9 个常用的 JavaScript 函数。

函数是 JavaScript 最重要的方面之一。如果没有 JavaScript 函数,它将非常有限。javascript 中的函数用于执行特定的操作或任务。

它们可以写入代码中,也可以使用 Function 构造函数创建。

Java 中的 Javascript 函数或方法可以接受参数和返回值。参数是在调用函数时传递给函数的值。返回值是函数执行后返回的值。

函数可以定义在其他函数内部,称为嵌套函数。嵌套函数可以访问外部函数的变量和参数。

这允许一些有趣且强大的编程技术。

作为一种编程语言,JavaScript 具有许多使其独特且重要的特性。这些功能之一是功能。

Javascript 函数对于 Angular 等其他框架也很重要。Angular 是一个 JavaScript 框架,用于在 JavaScript、HTML 和 TypeScript 中构建 Web 应用程序和应用程序。

Angular 被全世界数百万的开发人员使用。它是用于构建单页应用程序的最流行的框架之一。

本文将通过示例探索 9 个常用的 JavaScript 函数。

1. JavaScript 过滤器

JavaScript 中的 filter 函数用于根据特定条件从数组中过滤掉元素。换句话说,过滤器函数将返回一个新数组,其中仅包含满足条件的那些元素。

例如,如果我们有一个数字数组并且我们只想获得偶数,我们可以使用带有检查偶数条件的过滤器函数。

类似地,如果我们有一个对象数组并且只想获取具有某个属性值的对象,我们可以使用带有检查该属性值的条件的过滤器函数。过滤器功能还有许多其他用途。

JavaScript 过滤器示例:

// Array Filter function let numbers = [15, 2, 50, 55, 90, 5, 4, 9, 10]; console.log(numbers.filter(number => number % 2 == 1)); // Filtering odd numbers => result is [15, 55, 5, 9]


2. Javascript foreach

Javascript foreach 循环是在 JavaScript 中迭代数组的便捷工具。它允许您为数组中的每个元素执行一组特定的代码,而无需编写 for 循环。我们将看看 foreach 循环是如何工作的,以及如何在代码中使用它。

我们将讨论我们可以在 JavaScript 中使用 foreach 执行哪些类型的操作。JavaScript Foreach 是一种循环结构,可用于多种编程语言,包括 JavaScript。

foreach 的主要目的是允许程序员迭代数据集合,例如数组或列表。

要使用 JavaScript foreach,首先需要一个数组。这可以使用 Array() 构造函数或简单地将逗号分隔的值列表分配给变量来创建:

一旦你有了你的数组,你就可以使用 JavaScript foreach 循环开始迭代它。foreach 循环的语法如下:

JavaScript foreach 示例

<p id="items"></p> <script> let text = ""; const fruits = ["Apple", "Orange", "Cherry", "Banana"]; fruits.forEach(myFunction); document.getElementById("items").innerHTML = text; function myFunction(item, index) { index =index + 1 text += index + ": " + item + ""; } </script>


3. JavaScript 地图

JavaScript map 函数是 JavaScript 中的一个内置方法,它允许您处理数组中的每个元素。

JavaScript 中的 map() 方法根据函数转换数组中的元素。该函数在数组的每个元素上执行,元素作为参数传递。

JavaScript map() 方法返回一个包含转换后元素的新数组。

如果您有一个数字数组并且想要将它们加倍,您可以使用 map() 方法和一个将每个数字乘以 2 的函数。

在这种情况下,原始数组不会被修改。相反,使用双倍值创建一个新数组:

var newArr = arr.map(num => num * 2);

让我们看另一个 JavaScript 地图函数的例子。

const users = [ {firstname : "Abhishek", lastname: "kumar"}, {firstname : "jay", lastname: "sharma"}, {firstname : "rupal", lastname: "sharma"} ]; users.map(getFullName); function getFullName(item) { return [item.firstname,item.lastname].join(", ");} // Output: Abhishek kumar, jay sharma, rupal sharma,


4. JavaScript 连接

JavaScript 字符串连接是将两个或多个字符串连接在一起的过程。在 JavaScript 中连接字符串的最常见方法是使用 + 运算符。但是,还有其他方法可以做到这一点。

在 JavaScript 中连接字符串的一种方法是使用 += 运算符。该运算符将运算符右侧的字符串添加到运算符左侧的字符串中。例如:

str1 += str2; // 现在 str1 等于“Hello World”

在 JavaScript 中连接字符串的另一种方法是使用 .concat() 方法。

js concat 方法用于将两个或多个字符串合并在一起。如果您想用多个较小的字符串构建单个字符串,这很有用。

JavaScript Concat() 方法不会更改现有字符串,而是返回一个包含合并字符串文本的新字符串。

JavaScript 连接示例:

const arr1 = ["Abhishek", "rupal"]; const arr2 = ["divya", "rahul", "harsh"]; const allUsers = arr1.concat(arr2); // Output: Abhishek, rupal, divya, rahul, harsh const arr1 = ["Abhishek", "rupal"]; const arr2 = ["divya", "rahul", "harsh"]; const arr3 = ["kamal", "rohit"]; const allUsers = arr1.concat(arr2, arr3); // Output: Abhishek, rupal, divya, rahul, harsh, kamal, rohit


5. JavaScript 查找

使用数组时,find 函数可能是一个有用的工具。此函数将返回数组中满足给定条件的第一个元素。

如果我们有一个数字数组并且我们想找到第一个大于 5 的数字,我们可以使用 find 函数。JavaScript find 函数将回调作为其第一个参数。

此回调传递三个参数:正在处理的当前元素、该元素的索引和数组本身。

如果元素满足条件,回调应该返回 true,否则返回 false。在我们的示例中,如果当前元素大于 5,我们将返回 true。

JavaScript 查找功能不仅限于数字。它也可以用于字符串。

JavaScript 查找函数示例:

const marks = [30, 70, 98, 77]; console.log(marks.find(checkMarks)); function checkMarks(mark) { return mark > 90; } // 98


JavaScript find 函数的另一个例子:

const fruits = [ { name: "apple", count: 10 }, { name: "banana", count: 18 }, { name: "mango", count: 3 } ]; const findMango = fruits.find(fruit =>fruit.name === "mango"); // { name: "mango", count: 3}


6. JavaScript 查找索引

使用数组时,有时您可能需要查找特定元素的索引。这可以使用 JavaScript findIndex() 方法来完成。

JavaScript findIndex 方法返回数组中满足提供的测试函数的第一个元素的索引。否则,它返回 -1。

findindex JavascripS 方法类似于 JavaScript 的 find 函数,但它返回的是索引而不是值。

findIndex() 函数有两个 参数,一个回调函数和一个可选对象,该对象可用作回调函数中的 this 关键字。

JavaScript findIndex 函数示例:

const marks = [30, 70, 98, 77]; console.log(marks.findIndex(checkMarks)); function checkMarks(mark) { return mark > 90; } // 2


JavaScript findIndex 函数的另一个例子:

const fruits = [ { name: "apple", count: 10 }, { name: "banana", count: 18 }, { name: "mango", count: 3 } ]; const findMango = fruits.findIndex(fruit =>fruit.name === "mango"); // 2


7. JavaScript 包括

Javascript includes() 一个内置函数,用于检查一个字符串是否包含另一个字符串。如果找到指定的字符串,则返回 true。否则,它返回 false。

JavaScript包含函数区分大小写,这意味着它将区分大小写字母,这意味着它将“Java”和“java”视为两个不同的字符串。

要检查 js 字符串是否包含另一个字符串,只需将要检查的字符串作为第一个参数传入,将要检查的字符串作为第二个参数传入。

例如,让我们检查字符串“Hello World”是否包含单词“world”。由于搜索区分大小写,因此将返回 false。

const birds = ["Birds", "peacock", "Dove", "Sparrow"];console.log(birds.includes("Dove")); // true


8. JavaScript 拆分

JavaScript 拆分函数 JavaScript 是一个字符串函数,用于将字符串拆分为子字符串数组并返回新数组。

拆分(str,分隔符,限制)

原始字符串没有被修改。split 函数的语法是:

str — 要拆分的字符串。

separator — 用作分隔符的字符。如果省略,则使用单个空格 (' ') 作为分隔符。

limit — 一个整数,指定要进行的拆分次数。如果省略,字符串将被拆分为一个没有限制的子字符串数组。

分隔符是一个字符串,它定义了应该在哪里拆分字符串。限制是一个整数,指定最大拆分数。

如果没有指定分隔符,字符串将被空白字符分割。如果未指定限制,则默认为 0,即没有限制。

JavaScript split 函数的返回值是一个子字符串数组。如果字符串不能被拆分,它将返回一个空数组。

let text = "Hello this is akashminds";console.log(text.split(" "));// ["Hello", "this", "is", "akashminds"];let text = "Hello this is akashminds";console.log(text.split(" ", 3)); // ["akashminds"];


9. JavaScript 子字符串

JavaScript substr 函数用于提取字符串的一部分。它有两个参数:开始位置和子字符串的长度。该函数返回一个新字符串,其中包含原始字符串的提取部分。

如果起始位置为负数,则从字符串的末尾开始计数。如果省略长度参数,JavaScript substr 会提取从字符串开始位置到结尾的所有字符。

JavaScript substr 函数可用于提取字符串的一部分或通过连接两个子字符串来创建新字符串。它还可以用于找出给定字符串中是否存在某个字符或子字符串。

const test = "Hey!, this is Akashminds, have a nice day ahead.";console.log(test.substring(0, 30));// Hey!, this is Akashminds, have


作为用途最广泛、用途最广泛的编程语言之一,JavaScript 有着悠久的历史和光明的未来。在本文中,我们通过示例探索了最常用的 9 个 JavaScript 函数。

在 JavaScript 中使用函数有很多优点。

首先,如果你有很多代码需要重用,把它放在一个函数中可以很容易地在你需要的时候再次调用它。

其次,使用函数可以通过将代码分解成更小的部分来帮助您提高代码的可读性。

这些是最常用的 9 个 JavaScript 函数以及示例。掌握这些功能将帮助你编写更好的代码,成为更精通的程序员。

业办公管理系统,可以提供强大的模块化服务,帮助企业进行诸如制定计划、组织活动、上班考勤、领导管理和日志记录等功能,各个部分以模块化进行划分,软件具体可以分为部门管理、角色管理、用户管理、考勤管理、日志管理等部分。

这个系统使用了现在很流行的开发软件和相关技术,使用了目前最流行最方便的JAVA框架——SpringBoot框架,安全的shiro权限管理解决方案、前端使用了Thymeleaf作为模板语言,关系型数据库框架——mybatis,其中的MySQL数据库是中小型数据处理的最优选择方案。

SpringBoot框架是继spingMVC框架之后的有一个非常受欢迎的框架,具有很高的实用性,大大地减少了框架搭建之时的各种配置工作。是目前最优秀的JAVA框架,可以说是当SpringBoot框架出现之后,别的框架就黯然失色。该特性使开发人员能够摆脱复杂的配置工作和依赖的管理工作,更加关注业务逻辑。

项目特点

1.项目基于SpringBoot,简化了大量的配置和Maven依赖。
2.日志记录系统,记录用户的登陆、登出,用户执行的操作,通过@BizLog注解以及Spring中的AOP功能,记录了具体到用户的业务操作、登入登出,并且可以下载excel格式,方便查看。
3.利用Thymeleaf使得前端html代码看起来更加清晰。
4.通过角色管理来配置菜单,达到菜单为不同部门显示的目的,间接实现了权限的管理。
5.创建表后,通过LinGenerater类可生成包括html、js、Dao、Service、Controller等代码,复制进项目可直接使用。

javabean方式的配置文件

Lin中摒弃了传统的xml配置文件,使得配置文件更加清晰、简洁,下列为Shrio配置文件中的片段

@Configuration
public class ShiroConfig {
    /**
     * 安全管理器
     * @param rememberMeManager
     * @return
     */
    @Bean
    public DefaultWebSecurityManager securityManager(CookieRememberMeManager rememberMeManager){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRememberMeManager(rememberMeManager);
        securityManager.setRealm(this.shiroDbRealm());
        return securityManager;
    }
 
    @Bean
    public ShiroDbRealm shiroDbRealm(){
        return new ShiroDbRealm();
    }

代码生成

项目借助Mybatis Plus代码生成器生成Bean以及Dao,通过Velocity生成Controller、Service、ServiceImpl、html、js文件。在数据库中创建新表后,代码生成文件即可根据此表生成上述文件,实现了基本的表格展示、增删改查功能,可直接复制进项目中直接使用,添加菜单数据到数据库,即可在项目中看到此菜单页面。

    public static void main(String[] args) throws IOException {
//      参数为表名
        LinGenerater lg = new LinGenerater("thing");
//      此方法可以生成代码
        lg.execute();
//      此方法可以插入菜单数据
        lg.insertMenu("thing", "测试生成", "globe");
    }   

日志记录

日志记录通过aop(LogAop类)方式对所有包含@BizLog注解的方法进行aop切入,通过@Bizlog注解中的value属性来获取用户所做的操作,封装为日志类,异步存入数据库中(通过ScheduledThreadPoolExecutor类)。

    @Pointcut("@annotation(com.du.lin.annotation.BizLog)")
    public void logCut() {

    }

使用Thymeleaf使得html代码更简洁

下面是便签功能实现的部分片段。 后端:

     List<Memo> list = service.getUserMemoList();
     request.setAttribute("memolist", list);

前端html:

      <li th:each="memo,memoStat:${memolist}">
         <div>
           <small th:text="${memo.time}"></small>
              <small th:text="${memo.time}"></small>
                 <h4 th:text="${memo.title}"></h4>
                    <p th:text="${memo.text}"></p>
                      <a th:id="${memo.id}" onclick="deletememodialog(this)">   
                          <i class="fa fa-trash-o "></i></a>
                        </div>
                    </li>

所用框架

前端

  1. Bootstrap
  2. jQuery
  3. jqGrid
  4. jstree
  5. SweetAlert

后端

  1. SpringBoot
  2. MyBatis Plus
  3. Spring
  4. Thymeleaf
  5. Ehcache
  6. Kaptcha
  7. Shiro
  8. Velocity

项目演示视频如下:

<script src="https://lf6-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

获取源码请关注并私信“BG”