Express之Jade模板引擎

之前在建站:Node+MongoDb+Express简单实例一文中使用过express,本文就来介绍下expressjade模板引擎,为什么不介绍另一个express默认的模板引擎ejs了,因为我觉得jade更简洁,更符合我个人的喜好
注:jade因为版权问题已改名为pug了,具体可看这Renaming jade -> pug

安装执行


全局安装:

1
sudo npm install -g jade

接下来我们先看下jade命令的常用参数,,注意区分大小写


我们接着新建一个index.jade文件,代码如下所示很简单:

1
2
3
4
5
6
doctype
html
head
title hello
body
h1 hello world

接着在命令行执行jade index.jade,编译后的文件index.html内容如下:

1
<!DOCTYPE html><html><head><title>hello</title></head><body><h1>hello world</h1></body></html>

可以发现默认编译后的源码是被压缩过的,没有缩进不利于阅读,我们可以加上-P参数后就发现源码是经过被美化过的了

1
2
3
4
5
6
7
8
9
10
11
jade -P index.jade
<!DOCTYPE html>
<html>
<head>
<title>hello</title>
</head>
<body>
<h1>hello world</h1>
</body>
</html>

不过每次修改后都需要到终端重新编译,有点过于麻烦,我们可以加上-w参数实时监听文件变化保存后自动重新编译

1
jade -w -P index.jade

标签


html代码里标签基本都是成对存在的,包裹在尖括号里面,而在jade模板引擎里,不需要使用尖括号而且也不用成对存在,标签与标签之间的嵌套关系通过换行何缩进实现,比如以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
doctype
html
head
title hello world
body
h1 hello
span world
h1 test
//编译执行后结果:
<!DOCTYPE html>
<html>
<head>
<title>hello world</title>
</head>
<body>
<h1>hello<span>world</span></h1>
<h1>test</h1>
</body>
</html>

属性和文本


属性写在标签名后的括号内,多个属性用逗号分隔,css类名以及id名还可以直接通过与写css代码相同的形式紧贴在标签名后面,如果标签名未写,默认为div标签
标签名后第一个空格后面的内容会被编译成标签内的文本内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
doctype
html
head
title hello world
body
a(id="aId" class="aClass" href="https://www.luckyw.cn",target="_blank") luckyw
#divId.divClass hello world
//编译执行后结果:
<!DOCTYPE html>
<html>
<head>
<title>hello world</title>
</head>
<body>
<a id="aId" href="https://www.luckyw.cn" target="_blank" class="aClass">luckyw</a>
<div id="divId" class="divClass">hello world</div>
</body>
</html>>
</html>

多行文本


多行文本的实现有两种方式,第一种是在标签名后紧接写一个.,这样后面的内容会被jade模板视作文本域而保留换行符,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
p.
1a
2b
3c
4d
//编译执行后结果:
<p>
1a
2b
3c
4d
</p>

注:由于是文本域,因此使用这种写法里面要嵌套标签时,只能写原生的html标签了

1
2
3
4
5
6
7
8
9
10
11
12
13
p.
1a<span>abcd</span>
2b
3c
4d
//编译执行后结果:
<p>
1a<span>abcd</span>
2b
3c
4d
</p>

多行文本的第二种写法是在每行前加上|,同时使用jade语法嵌套标签,比如:

1
2
3
4
5
6
7
8
9
10
11
12
p
| 1a
span abcd
| 2b
| 3c
| 4d
//编译执行后结果:
<p>1a<span>abcd</span>2b
3c
4d
</p>

多行文本的写法不仅可用于p标签等,也常见于stylescript标签,例如:

1
2
3
4
script.
console.log("hello");
console.log("world");
console.log("luckyw.cn");

注释


单行注释:
通过”//“实现,用双斜杠的注释会被输出到html源码里
通过”//-“实现,不会被输出到html源码里

1
2
3
4
5
//我是一行注释,html源码可看到
//- 我是一行注释,不会输出到html源码里
//编译执行后结果:
<!--我是一行注释,html源码可看到-->

变量


变量声明很简单,前面加上-,之后使用js语法定义变量,使用时变量通过#{变量名}或者=变量名就行了,比如:

1
2
3
4
5
6
7
- var str = "hello world"
p #{str}
p=str
//编译执行后结果:
<p>hello world</p>
<p>hello world</p>

注意:以#{变量名}或者=变量名方式输出的变量数据会进行html转义,比如:

1
2
3
4
5
6
7
- var js = "<script>alert(1)</script>"
p #{js}
p=js
//编译执行后结果:
<p>&lt;script&gt;alert(1)&lt;/script&gt;</p>
<p>&lt;script&gt;alert(1)&lt;/script&gt;</p>

如果不想html转义,可以将#改成!即可

1
2
3
4
5
6
7
- var js = "<script>alert(1)</script>"
p !{js}
p!=js
//编译执行后结果:
<p><script>alert(1)</script></p>
<p><script>alert(1)</script></p>

那如果就想输出#{}!{}该怎么办呢?可以前面加\来让Jade引擎不编译变量

1
2
3
4
5
6
7
- var js = "<script>alert(1)</script>"
p \!{js}
p \#{js}
//编译执行后结果:
<p>!{js}</p>
<p>#{js}</p>

这两种写法#{变量名}=变量名输出的区别如下:

1
2
3
4
5
6
input(value="#{val}")
input(value=val)
//编译执行后结果:
<input value="undefined">
<input>

可以看出用#{}如果变量未定义,将会编译成undefined作为值,但用=来编译变量的话,如果变量未定义就忽略
有了变量就能轻松实现前后端分离,数据保存在JSON文件里,前端用Jade模板制作页面,在需要显示数据处用变量来实现,例如data.json文件里:

1
2
3
4
{
"title":"hello world",
"link":"https://luckyw.cn"
}

index.jade文件里:

1
2
3
4
5
6
doctype
html
head
title=title
body
a(href=link,target="_blank") luckyw

执行命令jade -P -w index.jade -O data.jsonJade文件里的变量被自动替换,编译出来的index.html:

1
2
3
4
5
6
7
<!DOCTYPE html>
<html>
<head>
<title>hello world</title>
</head>
<body><a href="https://luckyw.cn" target="_blank">luckyw</a></body>
</html>

流程控制


if else:

1
2
3
4
5
6
7
8
9
10
11
- var author="luckyw"
if author
p 作者:#{author}
else
p 无作者
if arr.length>0
p #{arr.join(", ")}
//编译执行后结果:
<p>作者:luckyw</p>
<p>node, express, jade</p>

for in

1
2
3
4
5
6
- for(var k in obj)
p #{obj[k]}
//编译执行后结果:
<p>luckyw</p>
<p>https://luckyw.cn</p>

each in:

1
2
3
4
5
6
7
- var obj = {"str":"luckyw","link":"https://luckyw.cn"}
each v,k in obj
p #{k}:#{v}
//编译执行后结果:
<p>str:luckyw</p>
<p>link:https://luckyw.cn</p>

while:

1
2
3
4
5
6
7
8
9
10
11
12
- var a = 0
ul
while a<4
li=a++
//编译执行后结果:
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>

case when:

1
2
3
4
5
6
7
8
9
10
- var flag = 0
case flag
when 1
p 对的
when 0: p 错误
default
p 错误
//编译执行后结果:
<p>错误</p>

mixin


之前在sass入门初体验中介绍过sass中的mixin,既能重用代码,而且维护简单,jade也支持mixin,可以理解为function
最简单的无参mixin,下面声明了一个mixin无参函数hello,调用时函数名前加上+:

1
2
3
4
5
6
mixin hello
p hello
+hello
//编译执行后结果:
<p>hello</p>

带参数的mixin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mixin info(name,skills)
p=name
ul.skills
each item in skills
li=item
+info("luckyw",["node","express","jade"])
//编译执行后结果:
<p>luckyw</p>
<ul class="skills">
<li>node</li>
<li>express</li>
<li>jade</li>
</ul>

继承


jade中使用blockextend实现模板的继承,block块就是定义一段html代码,hello就是我们定义的block块,定义好之后我们可以直接通过block hello调用从而实现代码的复用

1
2
3
4
5
6
7
block hello
p luckyw.cn
block hello
//编译执行后结果:
<p>luckyw</p>
<p>luckyw</p>

block真正的作用在于占位,供子文件继承,例如每个文件的页头都一样,就body里内容不一样,可以写一个header.jade文件:

1
2
3
4
5
6
doctype
html
head
title header
body
block content

然后改写index.jade,首先用extends继承自header.jade的,然后重写header.jade里的block content:

1
2
3
4
extends header
block content
p this is content

编译执行后结果:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<title>header</title>
</head>
<body>
<p>this is content</p>
</body>
</html>

如果您觉得我的文章对您有用,请随意打赏。

您的支持将鼓励我继续创作!

¥ 打赏支持

文章导航

目录

×
  1. 1. 安装执行
  2. 2. 标签
  3. 3. 属性和文本
  4. 4. 多行文本
  5. 5. 注释
  6. 6. 变量
  7. 7. 流程控制
  8. 8. mixin
  9. 9. 继承