kkcode24 / blog Goto Github PK
View Code? Open in Web Editor NEW喜欢请star,订阅请watch
喜欢请star,订阅请watch
nvm(nodejs version manager)
博客源地址
Windows 下安装 nvm 管理 nodejs 版本
. root 配置为当前 nvm.exe 所在目录
. path 配置为node快捷方式所在目录
. arch 配置为当前操作系统的位数(32/64)
. proxy 代理,不用配置
下载 nvm 包 地址:https://github.com/coreybutler/nvm-windows/releases,我们选择第一个:nvm-noinstall.zip 下载完成后解压到一个地方,比如: C:\dev\nvm 里面的文件列表是这样的:elevate.cmd、elevate.vbs、install.cmd、LICENSE、nvm.exe
右键以管理员的身份运行 install.cmd,弹出黑窗口,然后会让你输入”压缩文件解压或拷贝到的一个绝对路径” 先不用管它,直接回车,成功后,会在C盘的根目录生成一个settings.txt的文本文件,把这个文件剪切到C:\dev\nvm目录中,然后我们把它的内容修改成这样:
root: C:\dev\nvm
path: C:\dev\nodejs
arch: 64
proxy: none
node_mirror: http://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/
sysdm.cpl 系统属性面板
然后我们开始配置环境变量了,因为刚刚点击了install.cmd的文件,那么会在环境变量的系统变量中,生成两个环境变量:NVM_HOME 和 NVM_SYMLINK 我们开始修改这两个变量名的变量值:NVM_HOME的变量值为:C:\dev\nvm; NVM_SYMLINK的变量值为:C:\dev\nodejs
我们还会发现,在Path中也会自动添加上C:\dev\nvm;或者是C:\dev\nodejs,如果有的话,把他们删掉,没有的话更好,我们自己来配置,在Path的最前面输入: ;%NVM_HOME%;%NVM_SYMLINK%;
打开一个cmd窗口输入命令:nvm v ,那么我们会看到当前nvm的版本信息。然后我们可以安装nodejs了。
继续输入命令:nvm install latest 如果网络畅通,我们会看到正在下载的提示,下载完成后 会让你use那个最新的node版本。
如果你是第一次下载,在use之前,C:\dev目录下是没有nodejs这个文件夹的,在输入比如: nvm use 5.11.0 之后,你会发现,C:\dev目录下多了一个nodejs文件夹,这个文件夹不是单纯的文件夹,它是一个快捷方式,指向了 C:\dev\nvm 里的 v5.11.0 文件夹。
同样的咱们可以下载其他版本的nodejs,这样通过命令:nvm use 版本号 比如:nvm use 5.11.0就可以轻松实现版本切换了。
备注: 如果你的电脑系统是32 位的,那么在下载nodejs版本的时候,一定要指明 32 如: nvm install 5.11.0 32 这样在32位的电脑系统中,才可以使用,默认是64位的。
npm有两层含义,第一是npm这个开源的模块登记和管理系统,也就是这个站点:https://www.npmjs.com。
第二个指的是 nodejs package manager 也就是nodejs的包管理工具。我们主要说的就是这一个。
在每个版本的nodejs中,都会自带npm,为了统一起见,我们安装一个全局的npm工具,这个操作很有必要,因为我们需要安装一些全局的其他包,不会因为切换node版本造成原来下载过的包不可用。
npm config set prefix "C:\dev\nvm\npm"
回车prefix=C:\dev\nvm\npm
然后继续在命令中输入: npm install npm -g ,回车后会发现正在下载npm包。
在C:\dev\nvm\npm目录中可以看到下载中的文件,以后我们只要用npm安装包的时候加上 -g 就可以把包安装在我们刚刚配置的全局路径下了。
我们为这个npm配置环境变量: 变量名为:NPM_HOME,变量值为 :C:\dev\nvm\npm
在Path的最前面添加;%NPM_HOME%
,注意了,这个一定要添加在 %NVM_SYMLINK%
之前,所以我们直接把它放到Path的最前面
最后我们新打开一个命令窗口,输入npm -v ,此时我们使用的就是我们统一下载的npm包了。
同样的我们还可以安装cnpm工具,它是**版的npm镜像库,地址在这里:https://cnpmjs.org/,也是npm官方的一个拷贝,因为我们和外界有一堵墙隔着,所以用这个国内的比较快,淘宝也弄了一个和npm一样的镜像库,http://npm.taobao.org/,它和官方的npm每隔10分钟同步一次。安装方式:
npm install -g cnpm --registry=http://r.cnpmjs.org
或者用淘宝的npm install -g cnpm --registry=https://registry.npm.taoba.org
安装好了cnpm后,直接执行cnpm install 包名比如:cnpm install bower -g 就可以了。-g只是为了把包安装在全局路径下。如果不全局安装,也可以在当前目录中安装,不用-g就可以了。
nrm就是npm registry manager 也就是npm的镜像源管理工具,有时候国外资源太慢,那么我们可以用这个来切换镜像源。
我们只要通过这个命令:npm install -g nrm
就可以实现安装。
注意-g可以直接放到install的后面,我们以后也最好这样用,因为这样用,我们可以在cmd中上下箭头切换最近命令的时候,容易修改,更方便操作。安装完成后,我们就可以使用了。
nrm ls
用于展示所有可切换的镜像地址nrm use cnpm
我们这样就可以直接切换到cnpm上了。当然也可以按照上面罗列的其他内容进行切换。大概的比较一下session和cookie 的区别,不涉及深入的原理。
FreeMarker是一个用Java语言编写的模板引擎。它基于模板来生成文本输出。Freemarker与web容器无关,即在web运行时,它并不知道servlet或者HTTP,它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java等。目前在企业中,主要用freemarker做静态页面或是页面展示。
第一步:将freemarker的jar包添加进项目中。如果你建立的是maven项目,那么在pom.xml中直接引入依赖,maven会自动给下载这个jar包。
第二步:freemarker的运行并不依赖web容器,可以在java工程中运行。这样我们就可以创建一个测试方法进行测试
第三步:创建一个configuration对象。
第四步:告诉config对象模板文件存放的路径。
第五步:设置config的默认字符集。一般是utf-8。
第六步:从config对象中获得模板对象,需要制定一个模板文件的名字。
第七步:创建模板需要的数据集,可以试一个map对象,也可以试一个pojo。把模板需要的数据放入数据集。
第八步:创建一个Writer对象,指定生成文件保存的路径及文件名。
第九步:调用模板对象的process方法生成静态文字。需要两个参数数据集合writer对象。
第十步:关闭write对象。
FreeMarker的模板文件并不比HTML页面复杂多少,
FreeMarker模板文件主要由如下4个部分组成:
FreeMarker模板的例子,包含了以上所说的4个部分
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<#-- 注释部分 -->
<#-- 下面使用插值 -->
<h1>Welcome ${user} !</h1>
<p>We have these animals:</p>
<u1>
<#-- 使用FTL指令 -->
<#list animals as being>
<li>${being.name} for ${being.price} Euros
<#list>
<u1>
</body>
</html>
在FreeMarker中,使用FTL标签来使用指令,FreeMarker有3种FTL标签,这和HTML标签是完全类似的.
实际上,使用标签时前面的符号#也可能变成@。
如果该指令是一个用户指令而不是系统内建指令时,应将#符号改成@符号。
使用FTL标签时, 应该有正确的嵌套,而不是交叉使用,这和XML标签的用法完全一样。
如果全用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息。
FreeMarker会忽略FTL标签中的空白字符。
值得注意的是< , /> 和指令之间不允许有空白字符.
FreeMarker的插值有如下两种类型:
1,通用插值${expr};
2,数字格式化插值:#{expr}或#{expr;format}
对于通用插值,又可以分为以下4种情况:
1,插值结果为字符串值:直接输出表达式结果
2,插值结果为数字值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出。
可以使用内建的字符串函数格式化
单个插值,如下面的例子:
<#settion number_format="currency"/>
<#assign answer=42/>
${answer}
${answer?string} <#-- the same as ${answer} -->
${answer?string.number}
${answer?string.currency}
${answer?string.percent}
${answer}
输出结果是:
$42.00
$42.00
42
$42.00
4,200%
3,插值结果为日期值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化
${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}
${lastUpdated?string("EEE, MMM d, ''yy")}
${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}
输出结果是:
2008-04-08 08:08:08 Pacific Daylight Time
Tue, Apr 8, '03
Tuesday, April 08, 2003, 08:08:08 PM (PDT)
4.插值结果为布尔值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化
<#assign foo=true/>
${foo?string("yes", "no")}
输出结果是:
yes
数字格式化插值可采用#{expr;format}形式来格式化数字,其中format可以是:
mX:小数部分最小X位
MX:小数部分最大X位
如下面的例子:
<#assign x=2.582/>
<#assign y=4/>
#{x; M2} <#-- 输出2.58 -->
#{y; M2} <#-- 输出4 -->
#{x; m2} <#-- 输出2.6 -->
#{y; m2} <#-- 输出4.0 -->
#{x; m1M2} <#-- 输出2.58 -->
#{x; m1M2} <#-- 输出4.0 -->
表达式是FreeMarker模板的核心功能,表达式放置在插值语法${}之中时,表明需要输出表达式的值;
表达式语法也可与FreeMarker标签结合,用于控制输出。
实际上FreeMarker的表达式功能非常强大,它不仅支持直接指定值,输出变量值,
也支持字符串格式化输出和集合访问等功能.
使用直接指定值语法让FreeMarker直接输出插值中的值,而不是输出变量值.
直接指定值可以是字符串,数值,布尔值,集合和MAP对象.
直接指定字符串值使用单引号或双引号限定,如果字符串值中包含特殊字符需要转义,看下面的例子:
${"我的文件保存在C:\\盘"}
${'我名字是\"annlee\"'}
输出结果是:
我的文件保存在C:\盘
我名字是"annlee"
FreeMarker支持如下转义字符:
\";双引号(u0022)
\';单引号(u0027)
\\;反斜杠(u005C)
\n;换行(u000A)
\r;回车(u000D)
\t;Tab(u0009)
\b;退格键(u0008)
\f;Form feed(u000C)
\l;<
\g;>
\a;&
\{;{
\xCode;直接通过4位的16进制数来指定Unicode码,输出该unicode码对应的字符.
如果某段文本中包含大量的特殊符号,FreeMarker提供了另一种特殊格式:
可以在指定字符串内容的引号前增加r标记,在r标记后的文件将会直接输出.
看如下代码:
${r"${foo}"}
${r"C:\foo\bar"}
输出结果是:
${foo}
C:\foo\bar
表达式中的数值直接输出,不需要引号。
小数点使用"."分隔,不能使用分组","符号。
FreeMarker目前还不支持科学计数法,所以"1E3"是错误的。
在FreeMarker表达式中使用数值需要注意以下几点:
<h2>NBA西部:</h2>
<#list ["勇士", "火箭", "马刺", "森林狼", "雷霆", "开拓者", "鹈鹕"] as x>
${x}
</#list>
输出结果是:
NBA西部:
勇士
火箭
马刺
森林狼
雷霆
开拓者
鹈鹕
除此之外,集合元素也可以是表达式,例子如下:
[2 + 2, [1, 2, 3, 4], "whatnot"]
还可以使用数字范围定义数字集合,如2..5等同于[2, 3, 4, 5],但是更有效率.
注意,使用数字范围来定义集合时无需使用方括号,数字范围也支持反递增的数字范围,如5..2
Map对象使用花括号包括,Map中的key-value对之间以英文冒号":"分隔,多组key-value对之间以英文逗号","分隔.下面是一个例子:
{"语文":78, "数学":80}
Map对象的key和value都是表达式,但是key必须是字符串
FreeMarker的表达式输出变量时,这些变量可以是顶层变量,也可以是Map对象中的变量,还可以是集合中的变量,并可以使用点(.)语法来访问Java对象的属性.下面分别讨论这些情况
所谓顶层变量就是直接放在数据模型中的值,
例如有如下数据模型:
Map root = new HashMap(); //创建数据模型
root.put("name","annlee"); //name是一个顶层变量
对于顶层变量,直接使用${variableName}来输出变量值,变量名只能是字母,数字,下划线,$,@和#的组合,且不能以数字开头号。
为了输出上面的name的值,可以使用如下语法:
${name}
如果需要输出集合元素,则可以根据集合元素的索引来输出集合元素,集合元素的索引以方括号指定。
假设有索引:
["星期一","星期二","星期三","星期四","星期五","星期六","星期天"]。
该索引名为week,如果需要输出星期三,则可以使用如下语法:
${week[2]} //输出第三个集合元素
此外,FreeMarker还支持返回集合的子集合,如果需要返回集合的子集合,则可以使用如下语法:
week[3..5] //返回week集合的子集合,子集合中的元素是week集合中的第4-6个元素
这里的Map对象可以是直接HashMap的实例,甚至包括JavaBean实例,对于JavaBean实例而言,我们一样可以把其当成属性为key,属性值为value的Map实例。
为了输出Map元素的值,可以使用点语法或方括号语法.假如有下面的数据模型:
Map root = new HashMap();
Book book = new Book();
Author author = new Author();
author.setName("annlee");
author.setAddress("gz");
book.setName("struts2");
book.setAuthor(author);
root.put("info","struts");
root.put("book", book);
为了访问数据模型中名为struts2的书的作者的名字,可以使用如下语法:
book.author.name //全部使用点语法
book["author"].name
book.author["name"] //混合使用点语法和方括号语法
book["author"]["name"] //全部使用方括号语法
使用点语法时,变量名字有顶层变量一样的限制,但方括号语法没有该限制,因为名字可以是任意表达式的结果.
FreeMarker的表达式对字符串操作非常灵活,可以将字符串常量和变量连接起来,也可以返回字符串的子串等.
字符串连接有两种语法:
例如有如下数据模型:
Map root = new HashMap();
root.put("user","annlee");
下面将user变量和常量连接起来:
${"hello, ${user}!"} //使用第一种语法来连接
${"hello, " + user + "!"} //使用+号来连接
上面的输出字符串都是hello,annlee!,可以看出这两种语法的效果完全一样.
值得注意的是,${..}只能用于文本部分,不能用于表达式,下面的代码是错误的:
<#if ${isBig}>Wow!</#if>
<#if "${isBig}">Wow!</#if>
正确的写法是:
<#if isBig>Wow!</#if>
截取子串可以根据字符串的索引来进行,截取子串时如果只指定了一个索引值,则用于取得字符串中指定索引所对应的字符;
如果指定两个索引值,则返回两个索引中间的字符串子串。
假如有如下数据模型:
Map root = new HashMap();
root.put("book","struts2,freemarker");
可以通过如下语法来截取子串:
${book[0]}${book[4]} //结果是su
${book[1..4]} //结果是tru
这里所说的集合运算符是将两个集合连接成一个新的集合,连接集合的运算符是+,看如下的例子:
<#list ["勇士", "火箭", "马刺"]+["森林狼", "雷霆", "开拓者", "鹈鹕"] as x>
${x}
</#list>
输出结果是:
勇士
火箭
马刺
森林狼
雷霆
开拓者
鹈鹕
Map对象的连接运算符也是将两个Map对象连接成一个新的Map对象,Map对象的连接运算符是+,如果两个Map对象具有相同的key,则右边的值替代左边的值.看如下的例子:
<#assign scores = {"语文":86,"数学":78} + {"数学":87,"Java":93}>
语文成绩是${scores.语文}
数学成绩是${scores.数学}
Java成绩是${scores.Java}
输出结果是:
语文成绩是86
数学成绩是87
Java成绩是93
FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , % 看如下的代码:
<#assign x=5>
${ x * x - 100 }
${ x /2 }
${ 12 %10 }
输出结果是:
-75 2.5 2
在表达式中使用算术运算符时要注意以下几点:
使用内建的int函数可对数值取整,如:
<#assign x=5>
${ (x/2)?int }
${ 1.1?int }
${ 1.999?int }
${ -1.1?int }
${ -1.999?int }
结果是:2 1 1 -1 -1
表达式中支持的比较运算符有如下几个:
注意:
=和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,"x","x ","X"是不等的。
其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>
逻辑运算符有如下几个:
FreeMarker还提供了一些内建函数来转换输出,可以在任何变量后紧跟?,?后紧跟内建函数,就可以通过内建函数来轮换输出变量.
下面是常用的内建的字符串函数:
下面是集合的常用内建函数:
下面是数字值的常用内建函数:
例如:
<#assign test="Tom & Jerry">
${test?html}
${test?upper_case?html}
结果是:Tom & Jerry TOM & JERRY
FreeMarker对空值的处理非常严格,FreeMarker的变量必须有值,没有被赋值的变量就会抛出异常,因为FreeMarker未赋值的变量强制出错可以杜绝很多潜在的错误。
如缺失潜在的变量命名,或者其他变量错误.这里所说的空值,实际上也包括那些并不存在的变量,对于一个Java的 null值而言,我们认为这个变量是存在的,只是它的值为null,但对于FreeMarker模板而言,它无法理解null值,null值和不存在的变量完全相同.
为了处理缺失变量,FreeMarker提供了两个运算符:
其中,!运算符的用法有如下两种:
variable!或variable!defaultValue,第一种用法不给缺失的变量指定默认值,表明默认值是空字符串,长度为0的集合,或者长度为0的Map对象.
使用!指定默认值时,并不要求默认值的类型和变量类型相同.使用??运算符非常简单,它总是返回一个布尔值,用法为:variable??,如果该变量存在,返回true,否则返回false
FreeMarker中的运算符优先级如下(由高到低排列):
1,一元运算符:!
2,内建函数:?
3,乘除法:*, / , %
4,加减法:- , +
5,比较:> , < , >= , <= (lt , lte , gt , gte)
6,相等:== , = , !=
7,逻辑与:&&
8,逻辑或:||
9,数字范围:..
FreeMarker的FTL指令也是模板的重要组成部分,这些指令可实现对数据模型所包含数据的抚今迭代,分支控制.除此之外,还有一些重要的功能,也是通过FTL指令来实现的.
这是一个典型的分支控制指令,该指令的作用完全类似于Java语言中的if
if指令的语法格式如下:
<#if condition>...
<#elseif condition>...
<#elseif condition>...
<#else> ...
</#if>
例子如下:
<#assign age=23>
<#if (age>60)>老年人
<#elseif (age>40)>中年人
<#elseif (age>20)>青年人
<#else> 少年人
</#if>
输出结果是:青年人
上面的代码中的逻辑表达式用括号括起来主要是因为里面有>符号,由于FreeMarker会将>符号当成标签的结束字符,可能导致程序出错,为了避免这种情况,我们应该在凡是出现这些符号的地方都使用括号.
这些指令显然是分支指令,作用类似于Java的switch语句
switch指令的语法结构如下:
<#switch value>
<#case refValue>...<#break>
<#case refValue>...<#break>
<#default>...
</#switch>
list指令是一个迭代输出指令,用于迭代输出数据模型中的集合
list指令的语法格式如下:
<#list sequence as item>
...
</#list>
上面的语法格式中,sequence就是一个集合对象,也可以是一个表达式,但该表达式将返回一个集合对象,而item是一个任意的名字,就是被迭代输出的集合元素.此外,迭代集合对象时,还包含两个特殊的循环变量:
例子如下:
<#list ["勇士", "火箭", "马刺", "森林狼", "雷霆", "开拓者", "鹈鹕"] as x>
${x_index + 1}.${x}
<#if x_has_next>,</if>
<#if x="森林狼"><#break></#if>
</#list>
include指令的作用类似于JSP的包含指令,用于包含指定页.include指令的语法格式如下:
<#include filename [options]>
在上面的语法格式中,两个参数的解释如下:
该指令用于导入FreeMarker模板中的所有变量,并将该变量放置在指定的Map对象中,import指令的语法格式如下:
<#import "/lib/common.ftl" as com>
上面的代码将导入/lib/common.ftl模板文件中的所有变量,交将这些变量放置在一个名为com的Map对象中.
noparse指令指定FreeMarker不处理该指定里包含的内容
该指令的语法格式如下:
<#noparse>...</#noparse>
看如下的例子:
<#noparse>
<#list books as book>
<tr><td>${book.name}<td>作者:${book.author}
</#list>
</#noparse>
输出如下:
<#list books as book>
<tr><td>${book.name}<td>作者:${book.author}
</#list>
escape指令导致body区的插值都会被自动加上escape表达式,但不会影响字符串内的插值,只会影响到body内出现的插值
escape指令的语法格式如下:
<#escape identifier as expression>...
<#noescape>...</#noescape>
</#escape>
看如下的代码:
<#escape x as x?html>
First name:${firstName}
Last name:${lastName}
Maiden name:${maidenName}
</#escape>
上面的代码等同于:
First name:${firstName?html}
Last name:${lastName?html}
Maiden name:${maidenName?html}
escape指令在解析模板时起作用而不是在运行时起作用,除此之外,escape指令也嵌套使用,子escape继承父escape的规则,
如下例子:
<#escape x as x?html>
Customer Name:${customerName}
Items to ship;
<#escape x as itemCodeToNameMap[x]>
${itemCode1}
${itemCode2}
${itemCode3}
${itemCode4}
</#escape>
</#escape>
上面的代码类似于:
Customer Name:${customerName?html}
Items to ship;
${itemCodeToNameMap[itemCode1]?html}
${itemCodeToNameMap[itemCode2]?html}
${itemCodeToNameMap[itemCode3]?html}
${itemCodeToNameMap[itemCode4]?html}
对于放在escape指令中所有的插值而言,这此插值将被自动加上escape表达式,如果需要指定escape指令中某些插值无需添加escape表达式,则应该使用noescape指令,放在noescape指令中的插值将不会添加escape表达式.
assign指令在前面已经使用了多次,它用于为该模板页面创建或替换一个顶层变量,assign指令的用法有多种,包含创建或替换一个顶层变量, 或者创建或替换多个变量等
它的最简单的语法如下:
<#assign name=value [in namespacehash]>
这个用法用于指定一个名为name的变量,该变量的值为value,此外,FreeMarker允许在使用 assign指令里增加in子句,in子句用于将创建的name变量放入namespacehash命名空间中.
assign指令还有如下用法:
<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>
这个语法可以同时创建或替换多个顶层变量,此外,还有一种复杂的用法,如果需要创建或替换的变量值是一个复杂的表达式,
则可以使用如下语法格式:
<#assign name [in namespacehash]>capture this</#assign>
在这个语法中,是指将assign指令的内容赋值给name变量.如下例子:
<#assign x>
<#list ["勇士", "火箭", "马刺", "森林狼", "雷霆", "开拓者", "鹈鹕"] as n>
${n}
</#list>
</#assign>
${x}
上面的代码将产生如下输出: 勇士 马刺 森林狼 雷霆 开拓者 鹈鹕
虽然assign指定了这种复杂变量值的用法,但是我们也不要滥用这种用法,
如下例子:
<#assign x>
Hello ${user}!
</#assign>
以上代码改为如下写法更合适:
<#assign x="Hello ${user}!">
该指令用于设置FreeMarker的运行环境
该指令的语法格式如下:<#setting name=value>
在这个格式中,name的取值范围包含如下几个:
macro可以用于实现自定义指令,通过使用自定义指令,可以将一段模板片段定义成一个用户指令,使用macro指令的语法格式如下:
<#macro name param1 param2 ... paramN>
...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...
</#macro>
在上面的格式片段中,包含了如下几个部分:
看如下的例子:
//定义一个自定义指令
<#macro book>
j2ee
</#macro>
//使用刚才定义的指令
<@book />
上面的代码输出结果为:j2ee
在上面的代码中,可能很难看出自定义标签的用处,因为我们定义的book指令所包含的内容非常简单,实际上,自定义标签可包含非常多的内容,从而可以实现更好的代码复用.此外,还可以在定义自定义指令时,为自定义指令指定参数,看如下代码:
//定义一个自定义指令booklist是参数
<#macro book booklist>
<#list booklist as book>
${book}
</#list>
</#macro>
//使用刚刚定义的指令
<@book booklist=["spring","j2ee"] />
上面的代码为book指令传入了一个参数值,上面的代码的输出结果为:spring j2ee
不仅如此,还可以在自定义指令时使用nested指令来输出自定义指令的中间部分,看如下例子:
<#macro page title>
<html>
<head>
<title>FreeMarker示例页面 - ${title?html}</title>
</head>
<body>
<h1>${title?html}</h1>
<#nested> //用于引入用户自定义指令的标签体
</body>
</html>
</#macro>
上面的代码将一个HTML页面模板定义成一个page指令,则可以在其他页面中如此page指令:
//假设上面的模板页面名为common.ftl,导入页面
<#import "/common.ftl" as com>
<@com.page title="book list">
<u1>
<li>spring</li>
<li>j2ee</li>
</ul>
</@com.page>
从上面的例子可以看出,使用macro和nested指令可以非常容易地实现页面装饰效果,此外,还可以在使用nested指令时,指定一个或多个循环变量,看如下代码:
<#macro book>
<#nested 1> //使用book指令时指定了一个循环变量值
<#nested 2>
</#macro>
<@book ;x> ${x} .图书</@book>
当使用nested指令传入变量值时,在使用该自定义指令时,就需要使用一个占位符(如book指令后的;x)。
上面的代码输出文本如下:
1 .图书 2 .图书
在nested指令中使用循环变量时,可以使用多个循环变量,看如下代码:
<#macro repeat count>
<#list 1..count as x> //使用nested指令时指定了三个循环变量
<#nested x, x/2, x==count>
</#list>
</#macro>
<@repeat count=4 ; c halfc last>
${c}. ${halfc}
<#if last> Last! </#if>
</@repeat>
上面的输出结果为:
1. 0.5 2. 1 3. 1.5 4. 2 Last;
return指令用于结束macro指令,一旦在macro指令中执行了return指令,则FreeMarker不会继续处理macro指令里的内容,看如下代码:
<#macro book>
spring
<#return>
j2ee
</#macro>
<@book />
上面的代码输出:spring,而j2ee位于return指令之后,不会输出.
常用指令列表:
if, else, elseif
switch, case, default, break
list, break
include
Import
compress
escape, noescape
assign
global
setting
macro, nested, return
t, lt, rt
最常用的3个概念
Webpack 是一个模块打包器。
它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
webpack中文网
webpack是高度可配置的,在进行使用webpack之前,我们先了解下它的四个核心概念: 入口(entry)、输出(output)、loader、插件(plugins)。
入口起点(entry point)。入口起点告诉webpack从哪里开始,并遵循着依赖关系图表知道要打包什么。可以将您应用程序的入口起点认为是根上下文(contextual root)或 app 第一个启动文件。
wenpack配置对象(webpack configuration object)
中的entry
属性来定义接口,简单示例如下: // webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
};
根据不同应用程序的需要,声明 entry 属性有多种方式。了解更多
将所有的资源(assets)归拢在一起后,还需要告诉webpack在哪里打包应用程序。webpack的output 属性描述了如何处理归拢在一起的代码(bundled code)。
// webpack.config.js
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
webpack的目标是让 webpack 聚焦于项目中的所有资源(asset),而浏览器不需要关注考虑这些(明确的说,这并不意味着所有资源(asset)都必须打包在一起)。webpack 把每个文件(.css, .html, .scss, .jpg, etc.) 都作为模块处理。然而 webpack 自身只理解JavaScript。webpack loader在文件被添加到依赖图中时,其转换为模块
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
// 在任何模块文件内部,可以使用__dirname变量获取当前模块文件所在目录的完整绝对路径。
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};
module.exports = config;
持续更新
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.