对于H-ui的体验与下载,大家可以直接访问他的官方网站:http://www.h-ui.net/H-ui.admin.shtml。我们用到的是H-ui.admin v3.1.3这款。
首先,为了方便接下来的时间里调试,先加入热部署的坐标。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
这里解释下optional这个属性: 当optional=true时,依赖不会传递,也就是当前项目依赖devtools;之后依赖该项目的项目如果想要使用devtools,需要重新引入。这绝不是控制当前热部署是否生效的开关。控制热部署时否生效的开关在配置当中。也就是spring.devtools.restart.enabled: true|false,默认的值是true;在yml中的配置如下:
#spring相关的配置
spring:
#热部署配置
devtools:
restart:
enabled: true
也就是修改java文件后spring boot会自动重启;修改thymeleaf模板后,会以最新的代码渲染,如果没有实时效果,需要在application中配置spring.thymeleaf.cache=false 说起配置,对于thymeleaf默认的路径等均可配置,大家查相关资料就可,这里不加赘述,直接上配置代码。
#spring相关的配置
spring:
#热部署配置
devtools:
restart:
enabled: true
#模板配置
thymeleaf:
cache: false
prefix: classpath:templates/
suffix: .html
mode: HTML5
encoding: UTF-8
content-type: text/html
然后,我们来确定项目的模板与结构,对于一个后台项目,为了方便扩展,这里建一个admin目录,用来存放后台所有的模块与页面。如图:
1、thymeleaf与H-ui静态资源
thymeleaf的静态资源目录默认是存放在src/main/resources/static中,也就是说,在引用静态资源的时候,是以static为省略的根目录。我们先创建该目录。并且将H-ui.admin所使用到的静态资源copy过来,如图:
2、访问controller
创建后台的入口,IndexController,如图:
代码为:
package com.ruiyi.business.web.admin;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* <p> Title: </p>
* <p> Description: </p>
* @user yangtao
* @date 2019年2月13日
* @版本 1.00
* @修改记录
* <pre>
* 版本 修改人 修改时间 修改内容描述
* ----------------------------------------
* 1.00 yangtao 2019年2月13日 初始化版本
* ----------------------------------------
* </pre>
*/
@Controller
@RequestMapping("/admin/index")
public class IndexController {
private Logger logger = LoggerFactory.getLogger(getClass());
@RequestMapping("/login")
public String login(HttpServletRequest request) {
logger.info("登录页面");
return "/admin/login";
}
@RequestMapping("/index")
public String index() {
logger.info("后台首页");
return "/admin/index";
}
@RequestMapping("/welcome")
public String welcome() {
return "/admin/welcome";
}
}
3、html页面
3.1、根据IndexController的跳转信息,创建对应的页面
如图:
将H-ui中的内容复制过来,将index.html,login.html,welcome.html这三个文件内容复制到项目对应的文件中。之前和admin并列的index.html就直接删除。启动访问后,得到的效果如下:
接下来就是引入相关的样式了。
3.2、thymeleaf引入H-ui静态资源
在引入样式之前,我们先看下,thymelef默认对静态资源是怎么访问的?按F12或者右键“检查”,我们看到如下图信息:
和我们的网址对比下:http://localhost:8090/admin/index/login;我们发现,thymeleaf对静态资源的默认访问方式是相对于当前页面的action访问,也就是用页面中的静态资源路径代替了login,如上图中的url错误提示:http://localhost:8090/admin/index/static/h-ui/css/H-ui.min.css,那么我们怎么处理呢?
首先在html标签中,加入对thymeleaf的引用
<html xmlns:th="http://www.thymeleaf.org" >
thymeleaf引入静态资源的语法是:引入js使用th:src="@{xxx}",引入css使用th:href="@{xxx}"。我们先采用相对路径来引入H-ui静态资源。这里以login.html页面为例:
修改后,访问的效果如图:
其实如果我们不用thymeleaf的语法,也一样可以达到效果:
大家都知道,在jsp的引入静态资源中一般会选择引入绝对路径,会将访问的baseUrl提取出来,作为一个变量,并在项目启动初始化好。如:ctx = "http://localhost:8080/projectName/",那么在页面中就只要使用${ctx}作为前缀使用就可以了。习惯了jsp的朋友们,在使用其它模板引擎的时候,多少都会有这样的思维定式。
其实从上篇thymeleaf的介绍中就可以看出,真正做到动静分离,在路径的选择上,相对于项目的路径引入要显得更加方便。
当然,在一些非常特殊的情况下,像变更协议,使用H5的base标签等,就会使用这种类似于jsp的动态获取baseUrl了,这里也全部列举下,例如:我们要获取baseUrl,可在base标签(base标签一般放在head标签内)中加入如下代码
<base th:href="${#httpServletRequest.getScheme() + '://' + #request.getServerName() + ':' + #httpServletRequest.serverPort + #request.contextPath}">
#httpServletRequest.getScheme() 协议
#request.getServerName() 服务器名
#httpServletRequest.serverPort 端口
#request.contextPath 根路径(默认为/),如果在springboot的配置文件中指定了项目名,就是项目名。
这里我特意的用多种表示方式,也就是说,#httpServletRequest和#request是等价的,getXXX方法与直接获取属性XXX是一样的。结果如下:
那么问题来了,我们该怎么处理呢?如果这个时候大家把用了thymeleaf语法处理的页面在复制到静态页面,再打开,大家会发现样式又起不了作用了。可想而知,只用html的语法就可以了。涉及到绝对路径的,加上对应的base标签就可以了。
可依照login.html中的方式,将index.html和welcome.html修改好
4、公共静态资源的封装与引用
对于公共css与js的封装与引用,也是所我们web开发的一项基本经验。我们就来重点学习下thymeleaf怎么封装与引用。
4.1、公共静态资源的封装
这里我们要用到thymeleaf中的fragment,fragment类似于JSP的tag,可以将多个地方出现的元素块用fragment封装起来。
为了好说明,这里就先上代码,在与index.html并列的位置创建一个common.html,代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="commonHeader(title)">
<title th:text="${title}"></title>
<!-- <base th:href="${#httpServletRequest.getScheme() + '://' + #request.getServerName() + ':' + #httpServletRequest.serverPort + #request.contextPath +'/admin/'}"> -->
<link rel="stylesheet" type="text/css" href="/admin/static/h-ui/css/H-ui.min.css" />
<link rel="stylesheet" type="text/css" href="/admin/static/h-ui.admin/css/H-ui.admin.css" />
<link rel="stylesheet" type="text/css" href="/admin/lib/Hui-iconfont/1.0.8/iconfont.css" />
<link rel="stylesheet" type="text/css" href="/admin/static/h-ui.admin/skin/default/skin.css" id="skin" />
<link rel="stylesheet" type="text/css" href="/admin/static/h-ui.admin/css/style.css" />
</head>
<div th:fragment="commonJs">
<script type="text/javascript" src="/admin/lib/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="/admin/lib/layer/2.4/layer.js"></script>
<script type="text/javascript" src="/admin/static/h-ui/js/H-ui.min.js"></script>
<script type="text/javascript" src="/admin/static/h-ui.admin/js/H-ui.admin.js"></script>
</div>
</html>
对以上代码的解释:
common.html中有段注释代码,放了一个base:<base th:href="${#httpServletRequest.getScheme() + '://' + #request.getServerName() + ':' + #httpServletRequest.serverPort + #request.contextPath +'/admin/'}">,其中,大家可以根据自己放置静态资源的位置编写自己的'/admin/'。
另封装了两块fragment,即commonHeader与commonJs,其中commonHeader允许在引用的同时传入一个参数,作为当前页面的标题。
4.2、公共静态资源的引用
thymeleaf页面引入fragment有三种方式,即:
th:insert:保留自己的主标签,保留th:fragment的主标签。
th:replace:不要自己的主标签,保留th:fragment的主标签。
th:include:保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)
关于三者的区别,大家自行百度。我们这里使用th:include语法,我们以index.html页面为例,如图:
对上图的说明:
th:include是不要th:fragment的主标签的,所以我们直接将commonHeader引入到head标签当中。而对于commonJs,这里为了使body标签看上去干净些,直接引入到div当中。
5、thymeleaf中JavaScript的使用
如果说thymeleaf有个比较坑的东西,我想就是与js的集成了。这其实是与我们的开发习惯有关系,因为我们习惯了直接在script标签中敲js代码。那么在thymeleaf模板中使用js应当注意些什么呢?
下面给一个通用的模板:
<script type="text/javascript" th:inline="javascript">
/*<![CDATA[*/
//这里面书写自己的js代码
/*]]>*/
</script>
如果没有/*<![CDATA[*/ 与 /*]]>*/的包裹,thymeleaf是不认这js语法的。
对于H-ui的基本集成就到这里了,在后面的博文中会一一集成datatables、ueditor、webUploader等。由于之后的业务操作与数据有关,下一篇先说明下springBoot集成mybatis-plus