前言:node.js
的模板引擎有多種,如:ejs
,Handlebars
,jade
。一開始首先學習了ejs
,但是發現其有一個很大的弊端,那就是它不能繼承(由於之前用的全部是thinkphp
的模板,所以用起來非常彆扭,只能進行include
,而不能extend
),於是轉爲jade
,將html
做了一層抽象的模板引擎。
安裝jade
利用npm全局安裝:
$ npm install jade --global
由於sublime對jade沒有高亮的支持,所以需要我們手動來安裝插件,進入到sublime下的Packages,然後執行下面命令即可:
git clone https://github.com/davidrios/jade-tmbundle.git
Hello World
先來進行一個簡單的小demo,感覺下jade
:
新建一個文件命名爲:demo.jade
:
doctype html
html
head
meta(charset="utf-8")
title Jade
body
h1 Hello World
終端中執行命令jade demo.jade
,會發現我們的文件夾下多了一個demo.html
,這個就編譯出來的html代碼,打開一開會非常的亂:
這個代碼是被壓縮過的,沒有任何可讀性,我們改下命令就可以得出具有可讀性的代碼,jade demo.jade -P
:
但是每次更改完文件,我們都要手動來執行一次命令這樣實在是太費時間了,我們可以採用jade demo.jade -P -w
,監控我們的jade
,一有改變自動編譯。
基本語法
- jade採取的是縮進的方式來確定其關係,並且無論是需要閉合的標籤還是單個標籤都是用其標籤名即可,如:
div
h1 Hello
br
div
h1 World
編譯成html
就是
<div>
<h1>Hello</h1>
</div><br>
<div>
<h1>World</h1>
</div>
- 設定
class
與id
:
div.tite#title
代表的就是<div class='title' id='title></div>'
在jade
中還可以將div.tite#title
簡寫爲.title#title
,也會被編譯成相應的div
- 設定其他屬性:
除了class
和id
,其餘屬性都要在括號內設定,如:
meta(charset="utf-8")
a(href="http://www.baidu.com", title="百度")
- 一行文本太長怎麼破:
這種情況是指,我們的文字太多,編譯器會換行,這樣我們的縮進就會被破壞,解決這個問題的方法有兩種:
一: 縮進後一個|
和一個空格:
p
| 1.aa
strong 11
| 2.bb
strong 22
| 3.cc
strong 33
| 4.dd
strong 44
二: 利用.
:
p.
1.aa<strong>11<strong>
2.bb<strong>22<strong>
3.cc<strong>22<strong>
4.dd<strong>44<strong>
注意:p的每一行內容,在.
後開始,利用.
我們還可以寫內置的樣式與腳本:
style.
body{
color: gray;
}
script.
var x = "123";
- 註釋:
jade的註釋有兩種:
一: 可以被編譯到我們的html
中:
// div#title 123
html中的顯示爲:
<!-- div#title 123-->
二:非緩存註釋,不能被編譯到html
中:
只需要在//
後加一個-
就可以//- #title 不會被編譯到html中
jade同時允許我們假如對ie
瀏覽器的條件判斷註釋,格式與html中一樣:
<!--[if IE 8]><strong>換瀏覽器吧</strong><![endif]-->
- 變量聲明:
在jade中可以進行變量的聲明,- var test = "zp1996"
,這樣我們就聲明瞭一個test
變量,要是想用這個變量的話也很簡單,利用#{test}
就可以,並且這個{}
內支持js
語法,如:#{test.toUpperCase()}
,得到的就是ZP1996
,作爲模板語言來說,當然可以接受外界傳來的數據,但是需要注意的是在jade聲明的變量優先級高於外面傳入的,我們來嘗試下外面傳入數據的方式,首先我們將demo.jade的title
寫成#{title}
,然後我們在終端中輸入下面命令:
$ jade index.jade -P -w --obj '{"title": "Hello World"}'
打開瀏覽器刷新下,可以看到我們的網頁的title值爲Hello World。我們也可以利用一個json
文件來進行數據的傳遞,新建一個data.json
:
// json文件內容
{
"title": "Hello World"
}
// 終端輸入命令
$ jade index.jade -P -w -O data.json
刷新瀏覽器,可以看到我們的title值仍爲Hello World
。
jade在拿變量的時候其實有兩種方式:
一:#{}
取值時對變量進行轉義,利用=
號同樣可以。
- var data = "<script>alert(1);</script>"
div #{data}
div= data //- 注意,此時=要緊挨着div且與data之間有一空格
// 編譯成html得:
<div><script>alert(1);</script></div>
<div><script>alert(1);</script></div>
但是=
號與#{}
也有不同,那就是在我們所取得變量是沒有定義的,用#{}
取值取出來的是undefined
,而=
取出來的是空字符串:
input(type="text", value="#{zp}")
input(type="text", value=zp)
// html
<input type="text" value="undefined">
<input type="text">
二: !{}
取值時不對變量進行轉義,利用!=
同樣可以
- var data = "<script>alert(1);</script>"
div !{data}
div!= data //- 注意,此時=要緊挨着div且與data之間有一空格
// 編譯成html得:
<div><script>alert(1);</script></div>
<div><script>alert(1);</script></div>
當我們需要在網頁上輸出#{}
和!{}
時,採用\#{}
和\!{}
就好。
流程控制語法
- js原生流程控制語句
jade支持js原生的流程控制語句,如遍歷對象屬性時的for...in
,遍歷數組時的for
,進行判斷時的if...else
:
- var arr = [1, 2, 3, 4];
ul
- for (var i = 0, len = arr.length; i < len; i++)
li #{arr[i]}
- var n = 0;
ul
while (n < 4)
li= n++
if (arr.length > 3)
p the length of arr is more than 3
else
p the length of arr is less than 3
// html
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<p>the length of arr is more than 3</p>
- each
jade提供了一些語法糖
each
來遍歷對象或者數組
unless
進行條件判斷,unless(x) = if (!x)
case when
來實現js原生的switch
- var obj = {x: 1, y: 2, z: 3};
each val, key in obj
p #{key}: #{val}
each val in obj
p #{val}
unless zp
p zp is undefined
case n
when 3
p n is three
when 4
p n is four
default
p n is n
// html
<p>x: 1</p>
<p>y: 2</p>
<p>z: 3</p>
<p>1</p>
<p>2</p>
<p>3</p>
<p>zp is undefined</p>
<p>n is four</p>
重用jade代碼塊
mixin
定義公共代碼(類似於函數)
在某些情況下,代碼可能經常會重用,就像函數一樣,mixin
就是爲了解決這一問題:
// 基本語法:
mixin test
p zp1996
+test
// 既然說了像函數一樣,那麼它肯定也可以帶有參數
mixin lessonsInfo(name, course)
p #{name}'s lessons:
ul
each val, id in course
li #{id}: #{val}
+lessonsInfo("zp", {"001": "數學分析", "002": "線性代數"});
// 還可以內聯代碼塊
mixin show
if block
block
else
p no content for the time being
+show
p 123
// 編譯後爲
p 123
+show
// 編譯後爲
p no content for the time being
// 同時還只是傳遞屬性
mixin attr(name)
p(class!=attributes.class) #{name}
+attr("attr")(class="demo")
// 編譯後:
<p class="demo">attr</p>
// 我們想要傳遞的是多個屬性
mixin attrs(name)
p&attributes(attributes) #{name}
+attrs("attrs")(class="demo", id="demo")
// 參數不確定時和和ES2015中箭頭函數的處理方式相同,就是...
mixin manyarg(name, ...items)
ul(class="#{name}")
each item in items
li #{item}
- 模板繼承
block demo
p this is a demo about how to use block
block demo
// 編譯後:
<p>this is a demo about how to use block</p>
<p>this is a demo about how to use block</p>
模板的繼承和thinkphp
的模板繼承語法基本類似,通過extend
來進行繼承,下面來看個例子:
// layout.jade
html
head
meta(charset="utf-8")
title jade
style.
body{
color: gray;
}
script.
var x = "123";
body
block item
p a item in layout.jade
block content
// item.jade
extends layout
block content
block item
p a item in item.jade
// 編譯後我們會發現的就是外面的那個item塊被裏面的這個item塊給覆蓋掉了
- include
通過include
我們可以將頁面抽象出一個個小塊,可以說形成一個組件化的方式,比如頭部,尾部,搜索框等,這樣利於我們的維護我們的頁面。
對於include
來說我既可以引入.jade
,也可以引入.html
文件。
// 我們的一個頁面的一個骨架
doctype html
html
head
meta(charset="utf-8")
title jade
body
include header
block content
include footer
jade與後臺交互
首先我們需要了解的就是jade
的API
,詳情請見:http://jade-lang.com/api/
經常用的的API有就是jade.renderFile(filename, options)
,filename
是jade
文件的一個路徑,options
是一些配置,如我們的jade
文件內變量名的值,pretty
是否進行格式化等;這個函數的返回值爲html
字符串
與後臺交互的一個demo:
https://github.com/zp1996/Hello-World-Follow/tree/master/learnjade
clone下來直接node app.js
就行不用npm install
本文參考:
慕課網—帶你學習Jade引擎