【Thymeleaf】spring boot模板引擎thymeleaf用法详解

快速入门Thymeleaf

  • 1️⃣ 什么是Thymeleaf?
  • 1️⃣ 模板入门
    • 2️⃣ 创建测试工程
    • 2️⃣ 配置文件
    • 2️⃣ 创建controller
    • 2️⃣ 写一个html页面
    • 2️⃣ 启动测试
  • 1️⃣ Thymeleaf基础
    • 2️⃣ 实体类
    • 2️⃣ 增加接口
    • 2️⃣ $符号使用
    • 2️⃣ *符号的使用
    • 2️⃣ @符号的使用
    • 2️⃣ #符号的使用
    • 2️⃣ 集合的遍历
    • 2️⃣ thymeleaf如何定义变量
    • 2️⃣ 字面量
    • 2️⃣ 字符串拼接方式
    • 2️⃣ 比较运算符
    • 2️⃣ 逻辑运算符
    • 2️⃣ 三目运算符
    • 2️⃣ 分支结构,th:if,th:unless,th:switch,th:case
    • 2️⃣ thymeleaf的一些常用的内置对象
    • 2️⃣ 内联

1️⃣ 什么是Thymeleaf?

Thymeleaf 是一个流行的模板引擎,该模板引擎采用 Java 语言开发。

模板引擎是一个技术名词,是跨领域跨平台的概念,在 Java 语言体系下有模板引擎,在 C#、PHP 语言体系下也有模板引擎,甚至在 JavaScript 中也会用到模板引擎技术,Java 生态下的模板引擎有 Thymeleaf 、Freemaker、Velocity、Beetl(国产) 等。

Thymeleaf 对网络环境不存在严格的要求,既能用于 Web 环境下,也能用于非 Web 环境下。在非 Web 环境下,他能直接显示模板上的静态数据;在 Web 环境下,它能像 Jsp 一样从后台接收数据并替换掉模板上的静态数据。它是基于 HTML 的,以 HTML 标签为载体,Thymeleaf 要寄托在 HTML 标签下实现。

SpringBoot 集成了 Thymeleaf 模板技术,并且 Spring Boot 官方也推荐使用 Thymeleaf 来替代 JSP 技术,Thymeleaf 是另外的一种模板技术,它本身并不属于 Spring Boot,Spring Boot只是很好地集成这种模板技术,作为前端页面的数据展示,在过去的 Java Web 开发中,我们往往会选择使用 Jsp 去完成页面的动态渲染,但是 jsp 需要翻译编译运行,效率低。

Thymeleaf 的官方网站:Thymeleaf

Thymeleaf 官方手册:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

在这里插入图片描述

1️⃣ 模板入门

2️⃣ 创建测试工程

创建一个freemarker 的测试工程专门用于freemarker的功能测试与模板的测试。

测试环境搭建目录:

导入依赖:

<!-- SpringBoot框架集成Thymeleaf的起步依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2️⃣ 配置文件

配置application.yml。

application.yml内容如下:

server:
  port: 8088 #服务端口

spring:
  main:
    allow-bean-definition-overriding: true
  application:
    name: thymeleaf-demo #指定服务名
  thymeleaf:
    cache: false  #关闭模板缓存,方便测试
    suffix: .html
    prefix: classpath:/templates/

2️⃣ 创建controller

创建Controller类,向Map中添加name,最后返回模板文件。

UserController.java内容如下:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author hanson.huang
 * @version V1.0
 * @date 2024/10/23 18:44
 **/
@Controller
public class UserController {

    @RequestMapping(value = "/message")
    public String message(Model model) {
        model.addAttribute("data","SpringBoot框架集成Thymeleaf模板引擎");
        return "message";
    }
}

2️⃣ 写一个html页面

HTML 页面的元素中加入以下属性:<html xmlns:th="http://www.thymeleaf.org">

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div th:text="${data}"></div>
<h2 th:text="${data}"></h2>
<p th:text="${data}"></p>
<span th:text="${data}"></span>
</body>
</html>

2️⃣ 启动测试

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ThymeleafDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(ThymeleafDemoApplication.class, args);
    }

}

测试结果:

在这里插入图片描述

在页面的源代码中,可以看到在html文件中,通过 th:text 获取到的数据是存放在标签体中的。

注 意 : Springboot 用 使 用 thymeleaf 作 为 视 图 展 示 , 约 定 将 模 板 文 件 放 置
在src/main/resource/templates 目录下,静态资源放置在 src/main/resource/static 目录下。

在这里插入图片描述

1️⃣ Thymeleaf基础

2️⃣ 实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private int age;
}

2️⃣ 增加接口

@GetMapping("/hello")
public String hello(Model model, HttpSession session) {
    session.setAttribute("name","Hanson");
    List<User> list = new ArrayList<>();
    for (int i = 0 ; i < 5; i++) {
        User user = new User();
        user.setId(i);
        user.setName("黄汉升"+i);
        user.setAge(18);
        list.add(user);
    }
    model.addAttribute("users",list);
    User user = new User();
    user.setId(11);
    user.setAge(18);
    user.setName("赵子龙");
    model.addAttribute("user",user);
    return "hello";
}

2️⃣ $符号使用

$符号主要是取对象中的数据

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div th:text="${user.id}"></div>
<div th:text="${user.name}"></div>
<div th:text="${user.age}"></div>
</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ *符号的使用

符号也可以取对象中的数据

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div th:object="${user}">
    <div th:text="*{id}"></div>
    <div th:text="*{name}"></div>
    <div th:text="*{age}"></div>
</div>

<div th:text="*{user.id}"></div>
<div th:text="*{user.name}"></div>
<div th:text="*{user.age}"></div>
</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ @符号的使用

@符号主要是用于引入文件

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--可以是全路径-->
<script th:Src="@{http://localhost:8088/hello.js}"></script>
<!--可以带参数-->
<script th:Src="@{http://localhost:8088/hello.js(name='yl',age=19)}"></script>
<!--~代表当前项目-->
<script th:Src="@{~/hello.js}"></script>
<!--也可以省略协议-->
<script th:Src="@{//localhost:8088/hello.js}"></script>

<img th:src="@{https://img01.51jobcdn.com/im/2021/avatar/female/avatar_toc_female12.png}" th:title="${user.name}" th:alt="${user.name}"/>


<script>
    // 确保在页面加载完成后调用 sayHello('Hanson')
    window.onload = function() {
        sayHello('Hanson');
    };
</script>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ #符号的使用

#符号主要是根据当前浏览器的语言去相对应的国际化配置文件中取值

在这里插入图片描述

在这里插入图片描述

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div th:text="#{hello}"></div>

</body>
</html>

2️⃣ 集合的遍历

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div>
    <table border="1px">
        <tr th:each="u,state : ${users}">
            <td th:text="${u.id}"></td>
            <td th:text="${u.name}"></td>
            <td th:text="${u.age}"></td>
            <!--当前的遍历索引,从0开始-->
            <td th:text="${state.index}"></td>
            <!--当前的遍历索引,从1开始-->
            <td th:text="${state.count}"></td>
            <!--集合元素的总个数-->
            <td th:text="${state.size}"></td>
            <!--当前遍历的对象-->
            <td th:text="${state.current}"></td>
            <!--当前遍历是否为奇数次遍历-->
            <td th:text="${state.even}"></td>
            <!--当前遍历是否为偶数次遍历-->
            <td th:text="${state.odd}"></td>
            <!--当前是否为第一次遍历-->
            <td th:text="${state.first}"></td>
            <!--当前是否为最后一次遍历-->
            <td th:text="${state.last}"></td>
        </tr>
    </table>
</div>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ thymeleaf如何定义变量

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--th:with可以定义变量-->
<div th:with="num=(100+100/100+90-1)">
    <div th:text="${num}"></div>
</div>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ 字面量

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div th:text="'枪出如龙'"></div>
<div th:text="100"></div>
<div th:text="true"></div>
<div th:text="hellohanson"></div>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ 字符串拼接方式

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div th:text="'java' + 'js'"></div>
<div th:text="'java' + ${user.name}"></div>
<div th:text="|java ${user.name}|"></div>


</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ 比较运算符

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div th:with="num=(100+100/100+90-1)">
    <!--第一,第四和第六为true-->
    <div th:text="${num} eq 190"></div>
    <div th:text="${num} ne 190"></div>
    <div th:text="${num} lt 190"></div>
    <div th:text="${num} le 190"></div>
    <div th:text="${num} gt 190"></div>
    <div th:text="${num} ge 190"></div>
</div>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ 逻辑运算符

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--false-->
<div th:text="9 eq 9 and 8 ne 8"></div>
<!--true-->
<div th:text="9 eq 9 or 8 ne 8"></div>
<!--false-->
<div th:text="not(9 eq 9 or 8 ne 8)"></div>
<!--false-->
<div th:text="!(9 eq 9 or 8 ne 8)"></div>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ 三目运算符

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div th:with="score=57">
    <div th:text="(${score} ge 60) ? '及格' : '不及格'"></div>
</div>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ 分支结构,th:if,th:unless,th:switch,th:case

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div>
    <table border="1px">
        <!--th:if只显示偶次数出现的数据,th:unless则是取反-->
        <tr th:each="u,state : ${users}" th:if="${state.odd}">
            <td th:text="${u.id}"></td>
            <td th:text="${u.name}"></td>
            <td th:text="${u.age}"></td>
            <!--当前的遍历索引,从0开始-->
            <td th:text="${state.index}"></td>
            <!--当前的遍历索引,从1开始-->
            <td th:text="${state.count}"></td>
            <!--集合元素的总个数-->
            <td th:text="${state.size}"></td>
            <!--当前遍历的对象-->
            <td th:text="${state.current}"></td>
            <!--当前遍历是否为奇数次遍历-->
            <td th:text="${state.even}"></td>
            <!--当前遍历是否为偶数次遍历-->
            <td th:text="${state.odd}"></td>
            <!--当前是否为第一次遍历-->
            <td th:text="${state.first}"></td>
            <!--当前是否为最后一次遍历-->
            <td th:text="${state.last}"></td>
        </tr>
    </table>
</div>

<!--switch case语句-->
<div>
    <table border="1px">
        <tr th:each="u,state : ${users}">
            <td th:text="${u.id}"></td>
            <td th:text="${u.name}"></td>
            <td th:text="${u.age}"></td>
            <!--当前的遍历索引,从0开始-->
            <td th:text="${state.index}"></td>
            <!--当前的遍历索引,从1开始-->
            <td th:text="${state.count}"></td>
            <!--集合元素的总个数-->
            <td th:text="${state.size}"></td>
            <!--当前遍历的对象-->
            <td th:text="${state.current}"></td>
            <!--当前遍历是否为奇数次遍历-->
            <td th:text="${state.even}"></td>
            <!--当前遍历是否为偶数次遍历-->
            <td th:text="${state.odd}"></td>
            <!--当前是否为第一次遍历-->
            <td th:text="${state.first}"></td>
            <!--当前是否为最后一次遍历-->
            <td th:text="${state.last}"></td>
            <td th:switch="${state.odd}">
                <span th:case="true">偶数</span>
                <span th:case="*">基数</span>
            </td>
        </tr>
    </table>
</div>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ thymeleaf的一些常用的内置对象

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--thymeleaf的一些常用的内置对象-->
<!--session对象-->
<div th:text="${#session.getAttribute('name')}"></div>
<!--lists对象-->
<div th:text="${#lists.size(users)}"></div>
<!--execInfo对象-->
<div th:text="${#execInfo.getProcessedTemplateName}"></div>

</body>
</html>

测试结果:

在这里插入图片描述

2️⃣ 内联

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--内联-->
<!--其实取对象里的值还有以下这两种方式-->
<div>hello [[${user.name}]]</div>
<div>hello [(${user.name})]</div>
<hr/>

<!--如下,第一种方式对内容进行转义了,第二种方式没有对内容进行转义-->
<div th:with="str='jq <b>a better language</b>'">
    <div>[[${str}]]</div>
    <div>[(${str})]</div>
</div>

<script th:inline="javascript">
    var name = [[${user.name}]]
    console.log(name)
</script>

</body>
</html>

测试结果:

在这里插入图片描述

至此便是本文章关于Thymeleaf简单的基础入门<(▰˘◡˘▰)

本文代码:github

往期文章推荐《【FreeMarker】一文快速入门FreeMarker》

后期会更新模型到引擎最后导出pdf整个流程!!!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/899377.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文掌握异步web框架FastAPI(五)-- 中间件(测试环境、访问速率限制、请求体解析、自定义认证、重试机制、请求频率统计、路径重写)

接上篇:一文掌握异步web框架FastAPI(四)-CSDN博客 目录 七、中间件 15、测试环境中间件 16、访问速率限制中间件,即限制每个IP特定时间内的请求数(基于内存,生产上要使用数据库) 1)限制单ip访问速率 2)增加限制单ip并发(跟上面的一样,也是限制每个IP特定时间内的请…

??? 命令行形式的简单功能的计算器的Shell脚本

文章目录 需求编码Way1Way2&#xff1a; 测试 需求 需求分析&#xff1a; 支持浮点型&#xff1a;使用let命令 编码 Way1 用下循环吧&#xff01; #!/bin/bash # Author: # Date: # Description:# functions defines: input_check_to_startup() {num1$1num2$2isNum_statu…

Node版本管理nvm

公司项目比较多&#xff0c;且有历史包袱&#xff0c;没时间升级&#xff0c;高版本的node无法在低版本项目中打包编译&#xff1b; 下载地址 gitHub地址 nvm-setup.zip&#xff1a;安装版&#xff0c;推荐使用 nvm-setup.exe 常用指令 // 查看版本信息 nvm -v // 查看能安装…

《线下学习受局限,知识付费小程序开启新篇》

在知识大爆炸的时代&#xff0c;人们对知识的渴望从未如此强烈。然而&#xff0c;传统的线下学习方式却逐渐显露出诸多局限。 线下学习往往受到时间和空间的严格限制。为了参加一场培训课程或者讲座&#xff0c;你可能需要在特定的时间赶到特定的地点&#xff0c;这对于忙碌的…

大数据-188 Elasticsearch - ELK 家族 Logstash Output 插件

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

基于开源Jetlinks物联网平台协议包-MQTT自定义主题数据的编解码

目录 前言 1.下载官方协议包 2.解压 3.自定义主题 4.重写解码方法 5.以下是我解析后接收到的数据 前言 最近这段时间&#xff0c;一直在用开源的Jetlinks物联网平台在学习&#xff0c;偶尔有一次机会接触到物联网设备对接&#xff0c;在协议对接的时候&#xff0c;遇到了…

400行程序写一个实时操作系统(十):用面向对象思想构建抢占式内核

前言 通过前几章的学习&#xff0c;我们学会了如何为RTOS设计一个合理的内存管理算法。现在&#xff0c;是时候学习设计RTOS内核了。 关于RTOS内核的文章也有很多&#xff0c;但都有一点先射箭再化靶子的意味。要么是代码连篇解释却寥寥无几&#xff0c;要么是要先怎么样再怎么…

【星闪开发连载】WS63E模块连接华为IoT云

目录 引言 WS63E对MQTT的支持 程序修改 测试结果 结语 引言 在上一篇博文中已经介绍了WiFi的使用。今天介绍一下如何使用MQTT协议连接到华为云上。 WS63E对MQTT的支持 WS63E的代码参考直接提供了MQTT的支持&#xff0c;文档介绍见docs/board/WS63V100 MQTT 开发指南.pd…

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】 一、前文回顾二、CMSIS-NN简介2.1 为什么介绍CMSIS-NN&#xff1f;2.2 CMSIS-NN是什么&#xff1f;2.3 CMSIS-NN核心特性2.4 CMSIS-NN算子支持 三、TFLMCMSIS-NN集成3.1 包含TFLM的STM32项目3.2 理解TFLM…

如何在Windows平台下基于Whisper来训练自己的数据

0. 简介 最近快到1024程序员节了&#xff0c;再给大家上点干活。Whisper是openai开源的一个语音转文字模型。也是现在识别效果最好的离线数据模型&#xff0c;但是我们发现我们在完成一些中英文或者专业术语对话的时候。这时候表现的效果就比较差了。而这一步就得用微调的方式…

EM算法(期望最大算法、Expectation Maximization Algorithm)

EM算法&#xff08;期望最大算法、Expectation Maximization Algorithm) 引言 EM算法&#xff0c;全称为期望最大&#xff08;Expectation Maximization&#xff09;算法&#xff0c;是一种从不完全数据或有数据丢失的数据集&#xff08;存在隐含变量&#xff09;中求解概率模…

Oracle单实例静默安装

oracle 11g单实例静默安装 在CentOS上静默安装Oracle数据库 引言 在企业环境中&#xff0c;自动化和标准化是提高效率的关键。静默安装&#xff08;也称为无人值守安装&#xff09;是一种无需人工干预的安装方法&#xff0c;适用于大规模部署或需要重复安装的场景。本文将介…

【redis】初识非关系型数据库——redis

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 初识 Redis Redis是⼀种基于键值对&#xff08;key-value&#xff09;的NoSQL数据库&#xff0c;与很多键值对数据库不同的是&#xff0c;Redis 中的值可以是由string&#xff08;字符串&#xff09;、hash&#xff0…

【Python爬虫实战】多进程结合 BeautifulSoup 与 Scrapy 构建爬虫项目

#1024程序员节&#xff5c;征文# &#x1f308;个人主页&#xff1a;易辰君-CSDN博客 &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html ​ 前言 在大数据时代&#xff0c;爬虫技术是获取和处理网络数据的利器。面对需要处理大…

ChatGPT实现旅游推荐微信小程序

随着旅游行业的快速发展&#xff0c;个性化推荐已成为提升用户体验的重要手段。通过AI技术&#xff0c;提供一个智能旅游推荐小程序&#xff0c;使用户能够轻松获取定制化的旅行建议。 项目概述 项目目标 开发一个AI旅游推荐小程序&#xff0c;基于用户输入的旅行偏好&#…

Visual Studio安装图文详解教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 教程说明 本教程旨在详细介绍 Visual Studio 社区版的安装过程及其注意事项。 Visual Studio简介 Visual Studio 社区版功能完备且可扩展的免费 IDE&#xff0c;可用于创…

【WPF】中Dispatcher的DispatcherPriority参数使用

在 WPF 中&#xff0c;DispatcherPriority 参数用于指定通过 Dispatcher 调度的操作的执行优先级。加入 DispatcherPriority 参数的情况通常取决于你希望操作何时以及如何被执行。 1.Dispatcher的DispatcherPriority参数使用 以下是几种情况和示例说明&#xff1a; 1.1 需要…

【STM32 Blue Pill编程实例】-控制步进电机(ULN2003+28BYJ-48)

控制步进电机(ULN2003+28BYJ-48) 文章目录 控制步进电机(ULN2003+28BYJ-48)1、步进电机介绍2、ULN2003步进电机驱动模块3、硬件准备及接线4、模块配置3.1 定时器配置3.2 ULN2003输入引脚配置4、代码实现在本文中,我们将介使用 STM32Cube IDE 使用 ULN2003 电机驱动器来控制28B…

自由学习记录(14)

unity操作问题 位置&#xff1a;子物体的位置是相对于父物体的。如果你移动父物体&#xff0c;子物体会保持相对于父物体的相对位置&#xff0c;跟着一起移动。 旋转&#xff1a;子物体的旋转也是相对于父物体的。旋转父物体会导致子物体围绕父物体的原点旋转。 缩放&#xf…

【HarmonyOS NEXT】鸿蒙开发环境准备

0. 引言 看了发布会以后&#xff0c;热血澎湃啊&#xff0c;是时候学学把自己做的一些小工具搞成鸿蒙版了&#xff01;&#xff01;&#xff01; 1. 开发工具下载 下载地址&#xff1a;https://pan.quark.cn/s/08ddebdb7a20 工具版本会不定时更新&#xff0c;下载最新版即可…