Express之Jade模板引擎

luckyw

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

安装执行


全局安装:

sudo npm install -g jade

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

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

doctype
html
    head
        title hello
    body
        h1 hello world

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

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

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

jade -P index.jade

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

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

jade -w -P index.jade

标签


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

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标签
标签名后第一个空格后面的内容会被编译成标签内的文本内容

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模板视作文本域而保留换行符,例如:

p.
    1a
    2b
    3c
    4d

//编译执行后结果:
<p>
  1a
  2b
  3c
  4d
</p>

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

p.
    1a<span>abcd</span>
    2b
    3c
    4d

//编译执行后结果:
<p>
  1a<span>abcd</span>
  2b
  3c
  4d
</p>

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

p
    | 1a
    span abcd
    | 2b
    | 3c
    | 4d

//编译执行后结果:
<p>1a<span>abcd</span>2b
  3c
  4d
</p>

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

script.
  console.log("hello");
  console.log("world");
  console.log("luckyw.cn");

注释


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

//我是一行注释,html源码可看到
//- 我是一行注释,不会输出到html源码里

//编译执行后结果:
<!--我是一行注释,html源码可看到-->

变量


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

- var str = "hello world"
p #{str}
p=str

//编译执行后结果:
<p>hello world</p>
<p>hello world</p>

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

- 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转义,可以将#改成!即可

- var js = "<script>alert(1)</script>"
p !{js}
p!=js

//编译执行后结果:
<p><script>alert(1)</script></p>
<p><script>alert(1)</script></p>

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

- var js = "<script>alert(1)</script>"
p \!{js}
p \#{js}

//编译执行后结果:
<p>!{js}</p>
<p>#{js}</p>

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

input(value="#{val}")
input(value=val)

//编译执行后结果:
<input value="undefined">
<input>

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

{
    "title":"hello world",
    "link":"https://luckyw.cn"
}

index.jade文件里:

doctype
html
    head
        title=title
    body
        a(href=link,target="_blank") luckyw

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

<!DOCTYPE html>
<html>
  <head>
    <title>hello world</title>
  </head>
  <body><a href="https://luckyw.cn" target="_blank">luckyw</a></body>
</html>

流程控制


if else:

- 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

- for(var k in obj)
    p #{obj[k]}

//编译执行后结果:
<p>luckyw</p>
<p>https://luckyw.cn</p>

each in:

- 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:

- 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:

- 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,调用时函数名前加上+:

mixin hello
    p hello
+hello

//编译执行后结果:
<p>hello</p>

带参数的mixin:

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调用从而实现代码的复用

block hello
    p luckyw.cn
block hello

//编译执行后结果:
<p>luckyw</p>
<p>luckyw</p>

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

doctype
html
head
    title header
body
    block content

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

extends header

block content
    p this is content

编译执行后结果:

<!DOCTYPE html>
<html>
  <head>
    <title>header</title>
  </head>
  <body>
    <p>this is content</p>
  </body>
</html>
阅读 2.8k

luckyw
博客文章
677 声望
33 粉丝
0 条评论
677 声望
33 粉丝
宣传栏