/ dist目录在开源项目中是什么意思?
146
自从我dist/
在许多开源项目(通常在GitHub)上首次看到目录以来,我一直在想它的含义。
随着dist
,vendor
,lib
,src
,和许多其他的文件夹名称,我们看到很多时候,我有时想,我应该怎样命名我自己的文件夹。
如我错了请纠正我!
- src:包含源。有时,只有纯资源(有时带有缩小版本)取决于项目。
- 供应商:包含其他依赖项,例如其他开源项目。
- lib:好问题,
vendor
实际上真的很接近,具体取决于我们可以看到一个或另一个项目,或者两者兼有… - dist:据我所知,它包含“生产”文件,如果要使用该*库,*则应使用该文件。
/dist
表示“可分发”,即已编译的代码/库。
文件夹结构因构建系统和编程语言而异。以下是一些标准约定:
src/
:“源”文件以构建和开发项目。这是原始的源文件的位置,被编译成更少的文件之前dist/
,public/
或build/
。dist/
:“发行版”,已编译的代码/库,也称为public/
或build/
。供生产或公共使用的文件通常位于此处。assets/
:静态内容,例如图像,视频,音频,字体等。lib/
:外部依赖项(直接包含时)。test/
:项目的测试脚本,模拟等。node_modules/
:包括Npm使用的JS软件包的库和依赖项。vendor/
:包括Composer使用的PHP软件包的库和依赖项。bin/
:安装后添加到PATH的文件。
Markdown /文本文件:
README.md
:一个帮助文件,用于解决项目的设置,教程和文档。README.txt
也被使用。LICENSE.md
:授予您有关该项目的任何权利。LICENSE
或者LICENSE.txt
是许可文件名的变体,具有相同的内容。CONTRIBUTING.md
:如何为项目提供帮助。有时这在README.md
文件中已解决。
具体(这些可能会永远持续下去):
package.json
:定义Npm使用的JS软件包的库和依赖项。package-lock.json
:package.json
Npm使用从安装的依赖项的特定版本锁。composer.json
:定义Composer使用的PHP软件包的库和依赖项。composer.lock
:composer.json
由Composer使用的从安装的依赖项的特定版本锁。gulpfile.js
:用于定义与Gulp一起运行的功能和任务。.travis.yml
:Travis CI环境的配置文件。.gitignore
:Git 忽略的文件规范。
基础语法 基于 Thymeleaf 3.0.11.RELEASE 版本
文本标签 th:text/th:utext
用于文本内容的显示操作
- th:text 进行文本替换 不会解析html
- th:utext 进行文本替换 会解析html
*{}和${}表达式
正常情况下*{}和${}是一样的,但是 *{} 一般和 th:object进行连用来完成对象属性的简写
@RequestMapping("/th")
public String th(Model model){
User user = new User("jack",18);
model.setAttribute("user",user);
return "/course/th";
}
使用 ${} 操作
<p th:text="${user.name}"></p>
<p th:text="${user.age}"></p>
使用 *{} 操作
<p th:text="*{user.name}"></p>
<p th:text="*{user.age}"></p>
使用 *{} 特有操作
<div th:object="${user}">
<p th:text="*{name}"></p>
<p th:text="*{age}"></p>
</div>
@{} 链接网址表达式
一般和 th:href 、th:src进行结合使用,用于显示web 应用中的url链接。通过@{ }表达式 Thymeleaf 可以帮助我们拼接上web应用访问的全路径,同时我们可以通过()进行参数的拼接
模板代码:
<img th:src="@{/images/1.png}">
结果页面:
<img th:src="/ sbe/images/1.png">
模板代码:
<a th:href="@{/product/comments(proId=${prod.id})}">查看</a>
结果页面:
<a th:href="/sbe/product/comments?proId=2">查看</a>
模板代码:
<a th:href="@{/product/comments(proId=${prod.id},proId2=${prod.id})}">查看</a>
结果页面:
<a th:href="/sbe/product/comments?proId=1&proId2=2">查看</a>
条件判断 th:if / th:unless
th:if 当条件为true则显示
th:unless 条件为false则显示
代码演示:
@RequestMapping("/thif")
public String thif(Model model){
model.setAttribute("flag",true);
return "/course/thif";
}
模板页面:
<p th:if="${flag}">if判断</p>
结果页面:
<p>if判断</p>
模板页面:
<p th:unless="!${flag}">unless判断</p>
结果页面:
<p>unless判断</p>
switch
th:switch 我们可以通过switch来完成类似的条件表达式的操作
代码演示:
@RequestMapping("/thswitch")
public String thswitch(Model model){
User user = new User("jack",18);
model.setAttribute("user",user);
return "/course/thswitch";
}
模板页面:
<div th:switch="${user.name}">
<p th:case="jack">User is jack</p>
<p th:case="tom">User is tom</p>
</div>
结果页面:
<div>
<p>User is jack</p>
</div>
for 循环
th:each 遍历(可迭代)集合
代码演示:
@RequestMapping("/theach")
public String theach(Modle model){
List<User> userList = new ArrayList();
User user1 = new User("jack",11);
User user2 = new User("tom",12);
User user3 = new User("lucy",13);
User user4 = new User("musk",14);
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
model.setAttribute("userList",userList);
List<String> strList = new ArrayList();
strList.add("jack");
strList.add("tom");
strList.add("lucy");
strList.add("musk");
model.setAttribute("strList",strList);
return "/course/theach";
}
模板页面:
<table>
<tr>
<th>用户名称</th>
<th>用户年龄</th>
</tr>
<tr th:each="user : ${userList}" th:class="${userStat.odd}? 'odd'">
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
</tr>
</table>
-------------------------------------------------------------------------------
<table>
<tr>
<th>用户名称</th>
</tr>
<tr th:each="str : ${strList}" th:class="${strStat.odd}? 'odd'">
<td th:text="${str}"></td>
</tr>
</table>
th:href
用于声明在 a 标签上的href属性的链接 该语法会 和 @{ }表达式一起使用
代码演示:
@RequetMapping("/thhref")
public String thhref(Model model){
return "/course/thhref";
}
模板代码:
<a href="../home.html" th:href="@{/}">返回首页</a>
结果页面:
<a href="/sbe/">返回首页</a>
th:class
用于声明在标签上class属性信息
代码演示:
@RequestMapping("/thclass")
public String thclass(Model model){
return "/course/thclass";
}
模板页面:
<p th:class=" 'even'? 'even' : 'odd'" th:text=" 'even'? 'even' : 'odd'"></p>
结果页面:
<p class="even">even</p>
th:attr
用于声明html中或自定义属性信息
代码演示:
@RequestMapping("/thattr")
public String thattr(Model model){
return "/course/thattr";
}
模板页面:
<img th:attr="src=@{/images/1.png}">
结果页面:
<img src="/sbe/images/1.png">
th:value
用于声明html中value属性信息
代码演示:
@RequestMapping("/thvalue")
public String thvalue(Model model){
model.addAttribute("name","jack");
return "/course/thvalue";
}
模板页面:
<input type="text" th:value="${name}">
结果页面:
<input type="text" value="jack">
th:action
用于声明html form 表单标签中的action属性信息
代码演示:
@RequestMapping("/thaction")
public String thaction(Model model){
return "/course/thaction";
}
模板页面:
<form action="subscribe.html" th:action="@{/subscribe}">
<input type="text" name="name" value="abc">
</form>
结果页面:
<form action="/sbe/subscribe">
<input type="text" name="name" value="abc">
</form>
th:id
用于声明html id属性信息
th:inline
javascript内联 操作使用的语法,具体请参考下面内联操作相关介绍
th:onclick
用于声明html 中的onclick事件
代码演示:
@RequestMapping("/thonclick")
public String thonclick(Model model){
return "/course/thonclick";
}
模板页面:
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf8">
<title>th:onclick</title>
<script type="text/javascript">
function showUserInfo(){
alert("i am zhangsan")
}
</script>
</head>
<body>
<p th:onclick="'showUserInfo()'">点我</p>
</body>
</html>
结果页面:
<p onclick="showUserInfo()">点我</p>
th:selected
用于声明html中selected属性信息
代码演示:
@RequestMapping("/thselected")
public String thselected(Model model){
model.setAttribute("sex",1);
return "/course/thselected";
}
模板页面:
<select>
<option name="sex"></option>
<option th:selected="1 == ${sex}">男</option>
<option th:selected="0 == ${sex}">女</option>
</select>
结果页面:
<select>
<option name="sex"></option>
<opti onselected>男</option>
<option>女</option>
</select><>
th:src
用于声明html中的img的src属性信息
th:style
用于声明html中的标签的css样式信息
代码演示:
@RequestMapping("/thstyle")
public String thstyle(Model model){
model.setAttribute("isShow",true);
return "/course/thstyle";
}
模板页面:
<p th:style="'display:' + @{(${isShow} ? 'none' : 'block')} + ''" ></p>
结果页面:
<p style="display:none"></p>
th:with
用于thymeleaf模板页面中局部变量定义的使用
代码演示:
@RequestMapping("/thwith")
public String thwith(Model model){
model.setAttribute("today",new Date());
return "/course/thwith";
}
模板页面:
<p th:with="df='dd/MMM/yyyy HH:mm'">
today is :<span th:text="${#dates.format(today,df)}">13 February 2011</span>
</p>
结果压面:
<span>02/六月/2019 06:52</span>
@RequestMapping("/thwith")
public String thwith(Model model){
List<User> userList = new ArrayList();
userList.add(new User("jack",18));
userList.add(new User("tom",19));
userList.add(new User("lucy",20));
model.setAttribute("users",userList);
return "/course/thwith";
}
模板页面:
<div th:with="firstUser=${users[0]}">
<p th:text="${firstUser.name}"></p>
<p th:text="${firstUser.age}"></p>
</div>
结果页面:
<div>
<p>jack</p>
<p>18</p>
</div>
Elvis运算符
可以理解为简单判断是否为null的三元运算符的简写,如果值为null则显示默认值,如果不为null则显示原来的值
代码演示:
@RequestMapping("/elvis")
public String elvis(Model model){
model.setAttribute("age",null);
return "/course/elvis";
}
模板页面:
<p>Age:<span th:text="${age}?: '年龄为null'"></span></p>
结果页面:
<p>Age:<span>年龄为null</span></p>
三元运算符
我们可以在thymeleaf的语法中使用三元运算符 具体使用方法是在th:x 中通过 表达式?选项1:选项2
代码演示:
@RequestMapping("/threeElementOperation")
public String threeElementOperation(Model model){
return "/course/threeElementOperation";
}
模板页面:
<p th:class=" 'even' ? 'even' : 'odd'" th:text=" 'even' ? 'evne' : 'odd'"></p>
结果页面:
<p class="even">even</p>
代码演示:
@RequestMapping("/threeElementOperation")
public String threeElementOperation(Model model){
model.addAttribute("name","jack");
return "/course/threeElementOperation";
}
模板页面:
<p th:text="${name eq 'jack' ? '帅哥' : '美女'}"></p>
结果页面:
<p>帅哥</p>
条件表达式操作字符
- gt :great than (大于)
- ge:great equal (大于等于)
- eq:equal (等于)
- lt :less than (小于)
- le :less equal (小于等于)
- ne :not equal (不等于)
No-Operation(_)什么都不做
Elvis运算符的一种特殊简写操作,当显示的值为null,就什么也不做
代码演示:
@RequestMapping("/noOperation")
public String noOperation(Model model){
model.setAttribute("name",null);
return "/course/noOperation";
}
模板页面:
<p th:text="${name}? : _">No user authenticated</p>
结果页面:
<p>No user authenticated</p>
内联
如何使用内联操作
我们可以通过在 父标签声明 th:inline=“text” 来开启内联操作,如果想要整个页面使用可以直接声明在body上
模板页面:
<div th:inline="text">
<p>Hello,[[${user.name}]]!</p>
</div>
结果页面:
<div>
<p>Hello,jack!</p>
</div>
[[ ]] 对应于 th:text , [( )] 对应于 th:utext
禁用内联操作
在父标签或本标签上声明 th:inline=“none”
javascript内联
在script标签上声明 th:inline="javascript"然后就可以在script里使用内联操作了
<script th:inline="javascript">
var name = [[${name}]];
</script>
css内联
在Style标签上声明 th:inline="css"然后就可以在style使用内联操作了
<style th:inline="css">
div {
[[${ }]]: [[${ }]];
}
</style>
模板布局
定义引用片段代码
SpringBoot2.0 使用模板布局需要引入 thymeleaf的 thymeleaf-layout-dialect依赖
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
定义footer.html页面 该页面就是我们的引用片段代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>
我们可以通过 th:fargement 来定义引用片段,然后可以在其他页面进行引用
定义引用页面 index.html
!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:insert="~{footer :: copy}"></div>
</body>
</html>
通过 th:insert 和 ~{ } 片段引用表达式 进行引入footer.html中定义的片段
定义访问index页面的 controller
@Controller
@RequestMapping("/layout")
public class LayoutController{
@RequestMapping("/index")
public String index(Model model){
return "/layout/index";
}
}
结果页面:
<div>
<div> © 2011 The Good Thymes Virtual Grocery</div>
</div>
还可以这样写:
<div th:insert="footer :: copy"></div>
通过id属性来声明片段
我们可以通过 th:fragment 来定义引用片段,但是我们也可以通过在引用片段上声明id属性的方式进行片段的引用
定义引用片段代码模板页面 footer.html
!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="copy-section">
@copy;2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>
引用引用片段的模板页面:index.html
!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:insert="footer :: #copy-section">
</div>
</body>
</html>
结果页面:
<div>
<div id="copy-section">
@copy;2011 The Good Thymes Virtual Grocery
</div>
</div>
footer :: #copy-section 和 ~{footer :: #copy-section} 结果是一致的
th:insert 和 th:replace (和 th:include) 之间的区别
th:insert 是最简单的:它会将使用th:insert 的标签和 引用片段的内容都显示出来
th:replace 只显示引用片段的标签和内容
th:include 和 th:insert类似:只显示插入此片段的内容
@RequestMapping("/layout")
public class LayoutController{
@RequestMapping("/index2")
public String index2(Model model){
return "/layout/index2";
}
}
声明引用片段模板页面:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
</body>
</html>
引用片段模板页面:index2.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:insert="footer2 :: copy"></div>
<div th:replace="footer2 :: copy"></div>
<div th:include="footer2 :: copy"></div>
</body>
</html>
insert结果:
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
replace结果:
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
include结果:
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
带参数的引用片段
定义引用片段代码模板页面 footer.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:fragment="frag (onevar,twovar)">
<p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
</body>
</html>
引用:index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:insert="footer :: frag('a','b')"></div>
</body>
</html>
结果:
<div>
<div>
<p>'a' - 'b'</p>
</div>
</div>
###删除模板片段
预定义的工具对象
#dates:处理日期数据 生成,转换,获取日期的具体天数 年数
format操作:
#dates.format(date) 2019年5月30日 上午10时03分24秒
#dates.format(date,‘dd/MMM/yyyy HH:mm’) 30/五月/2019 10:03
Date[] datesArray = new Date[2];
datesArray[0] = date;
datesArray[1] = date2;
#dates.format(datesArray,‘yyyy-MM-dd HH:mm’)
2019-05-13 10:03(这里只显示一个日期)
List<Date> datesList = new ArrayList<>();
datesList.add(date);
datesList.add(date2);
model.setAttribute("datesList",datesList);
<p th:text="${#dates.listFormat(datesList,'dd/MMM/yyyy HH:mm')}"></p>
<p>[30/五月/2019 10:03, 30/五月/2018 00:00]</p>
获取日期属性操作
#dates.day(date)
#dates.month(date)
#dates.monthName(date) 五月
#dates.monthNameShort(date) 五月
#dates.year(date) 2022
#dates.dayOfWeek(date) 5
#dates.dayOfWeekName(date) 星期五
#dates.dayOfWeekNameShort(date) 星期五
#dates.hour(date)
#dates.minute(date)
#dates.second(date)
#dates.millisecond(date)
#dates.createNow() Thu May 30 10:15:55 CST 2019
#numbers:处理数字的转换
formatInteger:对不够位数数字进行补0
formatInteger:设置千位分隔符
fromatDecimal:精确小数点
formatPercent:设置百分号
sequence:生成数组
数字进行补0操作
#numbers.formatInteger(‘123’,4) 0123
#numbers.formatInteger(‘123’,3) 123
#numbers.formatInteger(‘123’,2) 123
#numbers.listFormatInteger(numList,3) [001,002,003]
千位分隔符操作
#numbers.formatInteger(‘1000’,2,‘POINT’) 1.000
#numbers.formatInteger(‘1000’,6,‘POINT’) 001.000
#numbers.formatInteger(‘1000’,7,‘POINT’) 0.001.000
#numbers.formatInteger(‘1000’,2,‘COMMA’) 1,000
#numbers.formatInteger(‘1000’,2,‘WHITESPACE’) 1 000
#numbers.formatInteger(‘1000’,2,‘NONE’) 1000
#numbers.formatInteger(‘1000’,2,‘DEFAULT’) 1,000
精确小数点操作
#numbers.formatDecimal(‘10.123’,3,2) 010.12
#numbers.formatDecimal(‘1000.123’,5,‘POINT’,2,‘COMMA’) 01.000,12
钱显示符号操作
#numbers.formatCurrency(‘1000’) $1000
百分比操作
#numbers.formatPercent(‘0.2’,2, 4) 20.0000%
#numbers.formatPercent(‘0.2’,3, 2) 020.00%
生成数组操作
<div th:each="num : ${#numbers.sequence(0,4)}">//0 1 2 3 4
<p th:text="${num}"></p>
</div>
结果:
<div>
<p>0</p>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
</div>
<div th:each="num : ${#numbers.sequence(0,4,1)}">//第三个参数为1 表示每次相差 1 -- 0 1 2 3 4
<p th:text="${num}"></p>
</div>
存疑
<div th:each="num : ${#numbers.sequence(0,10,2)}">//第三个参数为2 表示每次相差 2 -- 0 2 4 6 8 10
<p th:text="${num}"></p>
</div>
#strings
处理String的相关操作:
-
字符串转换(toString)
Object object = new Object(“123”);
#strings.toString(object)
List list = new ArrayLIst();
list.add(1);
list.add(2);
list.add(3);
#strings.toString(list);
输出:[1,2,3]
-
检查字符串是否为空(isEmpty)
String name = null;
#strings.isEmpty(name);
输出:true
List list = new ArrayList();
list.add(“jack”);
list.add(null);
#strings.listIsEmpty(list);
输出:[false,true]
Set set = new HashSet();
set.add(null);
set.add(“1”);
#strings.setIsEmpty(set);
输出:[true,false]
-
字符串是否为空替换操作(defaulString)
String name = null;
#strings.defualtString(name,"该name为null“);
输出:
该name为null
List list = new ArrayList();
list.add(“jack”);
list.add(null);
#strings.listDefaultString(list,“this name is null”);
输出:[jack,this name is null]
-
检查字符串中是否包含某个字符串(contains containsIgnoreCase)
#strings.contains(“abcde”,“bc”);
输出:true
-
检查字符串是以什么片段开头/结尾(startWith endWith)
#strings.startWith(“abcdef”,“abc”);
输出:true
#string.endWith(“jack”,“k”);
输出:true
-
截取(substring substringAfter)
和java想通
-
替换(replace)
#strings.replace(“tom”,“o”,“a”);
输出:tam
-
追加(头加prepend 、尾加append)
#strings.prepend(“abc”,“123”);
输出:123abc
#strings.append(“abc”,“123”);
输出:abc123
-
变更大小写(toUpperCase toLowerCase)
和java想通
-
length操作:
和java想通
-
拆分和组合字符串(arrayJoin arraySplit)
-
去空格(trim):去两边空格
#strings.trim(" abc ");
输出:abc
-
缩写文本(abbreviate)
#strings.abbreviate(“123456789”,“3”);
输出:123…
-
字符串连接(concat)
和java想通
#objects 处理Object对象的操作
nullSafe:obj不为空返回原来值,为空返回默认值
@RequestMapping("/objects")
public String objects(Model model){
object obj = null;
model.setAttribute("obj",obj);
}
#objects.nullSafe(obj,“该对象为null”)
输出:该对象为null
#bools:判断是否为true或是否为false的操作
数字 1 为 true,0 为 false
#bools.isTrue(1)
”on“ 为 true ,”off“ 为 false
#bools.isTrue(“on”)
“true” 为 true,“false” 为false
#bools.isTrue(“true”)
#arrays:处理数组的相关操作的内置对象
转换数组 toStringArray(array)、toIntegerArray
获取数组的长度 length(array)
判断数组是否为空 isEmpty(array)
是否包含某一个元素 contains(array,ele)
是否包含一批元素 containsAll(array,eles)
#lists:处理 list 相关操作的内置对象
计算长度(size(list))
检查list是否为空(isEmpty(list))
检查元素是否包含在list中(contains(list,ele)/containsAll(list,eles))
对给定的list副本排序:sort(list)
#sets:处理set相关操作的内置对象
转换为set:toSet()
计算长度:size(set)
检查set是否为空:isEmpty(set)
检查元素是否在set中:contains(set,ele)、containsAll(set,eles)
对给定的list副本排序:sort(set)
#maps:处理map相关操作的内置对象
计算长度:size(map)
检查map是否为空:isEmpty(map)
检查映射中是否包含键或值:containsKey(map,key)、containsAllKey(map,keys)、containsValue(map,value)
#aggregates:用户处理集合和数组的一些统计操作(数值类型)
求和:sum
求平均数:avg
处理基本类型或包装类型的数组或集合