Jade簡單教程

Express框架裏內嵌了Jade模板引擎。正好項目裏也要用到,本篇整理了下Jade的相關用法。css

  • 安裝與執行
  • 標籤和屬性
  • 多行文本
  • 變量
  • 語句
  • Mixin
  • 模板
  • 註釋
  • 過濾器

安裝與執行

安裝很簡單:html

npm install jade –global

安裝後本地隨便新建一個sample.jade文件,執行:前端

jade sample.jade

就能將其翻譯成標準的sample.html源文件了。執行時能夠帶上參數,經過jade -h查看支持的命令參數:jquery


經常使用的命令參數,好比-P(大寫,命令參數是大小寫敏感的)。Jade默認編譯出來的html源文件裏是沒有縮進的,不便於開發。加上-P參數後,編譯出來的html源文件裏就有縮進了:npm

jade -P sample.jade

還有-w用來watch監視jade文件,每次改動保存後自動編譯成html文件,省去手動執行命令的麻煩:json

jade -P -w sample.jade

-O用來給jade文件傳遞對象或JSON文件,用以替換模板內的變量:後端

jade -P -w sample.jade -O sample.json

標籤和屬性

傳統的HTML標籤寫尖括號很麻煩,Jade裏能夠省略尖括號,直接寫標籤名。標籤間的嵌套關係用換行加空格來實現。緊接在標籤名後加上.xx或#xx,就能給標籤添加css類名和id。標籤名後第一個空格後面的內容會被編譯成標籤內的文本內容。例如:sass

doctype html
html
  head
  body
    h1.titleClass#titleID My First Jade Page

//編譯出來的結果
<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <h1 id="titleID" class="titleClass">My First Jade Page</h1>
  </body>
</html>

是否是感受寫起來簡單多了。由於css類名和id是最經常使用的標籤屬性,因此Jade簡化了它倆的寫法,能夠緊接在標籤名後面。但標籤屬性的正統寫法應該是寫入()括號內,多個屬性用逗號隔開(css類名和id也能夠寫入()括號內):markdown

a(href='http://www.jackzxl.net', target='_blank') 個人主頁

//編譯出來的結果
<a href="http://www.jackzxl.net" target="_blank">個人主頁</a>

HTML裏最經常使用的標籤就是div了,因此Jade提供了第二種簡化寫法,若是不寫標籤名默認就是div:框架

.divClass#divID 我是一個div

//編譯出來的結果
<div id="divID" class="divClass">我是一個div</div>

多行文本

單行文本像上面這樣接在標籤名後的空格後面便可。多行文本有兩種寫法。第一種寫法是在標籤名後緊接一個.點。這樣後面的內容會被Jade模板視做文本域而保留換行符。例如:

p.
  第1行文本
  第2行文本
  第3行文本
  第4行文本

//編譯出來的結果
<p>
  第1行文本
  第2行文本
  第3行文本
  第4行文本
</p>

但因爲是文本域,所以用這種寫法的話,裏面要嵌套標籤時,只能寫原生的HTML標籤了:

p.
  第1行文本
  第2行文本
  第3行文本
  第4行文本

//編譯出來的結果
<p>
  <span>第1行文本</span>
  第2行文本
  第3行文本
  第4行文本
</p>

多行文本的第二種寫法是在每行前加上|豎線符。並且若是開發者以爲第一種寫法裏寫原生HTML標籤不爽,用這種寫法,能夠用Jade語法來嵌套標籤。例如:

p
  span 第1行文本
  | 第2行文本
  | 第3行文本
  | 第4行文本

//編譯出來的結果
<p><span>第1行文本</span>第2行文本
  第3行文本
  第4行文本
<p>

多行文本的寫法不只可用於p標籤等,也常見於style和script標籤,例如:

script.
  console.log("open mind");
  console.log("learning quick");
  console.log("work hard");

變量

若是僅僅上面這些快速編寫HTML的功能,那Jade也不必存在了。各類編輯器都有插件能夠實現這種快速編寫的功能,例如sublime的Emmet插件。模板引擎的真正強大之處能夠實現函數式的開發。先看變量。

變量聲明很簡單,前面加上-橫槓。使用變量只要#{變量名}就好了。例如:

- var cs = 'UTF-8'
meta(charset='#{cs}')

//編譯出來的結果
<meta charset="UTF-8">

但注意用#{}輸出的變量數據會執行HTML轉碼,例如:

- var alertData = '<script>alert(1);</script>'
p #{alertData}

//編譯出來的結果
<p><script>alert(1);</script></p>

本來想被執行的script腳本,被直接做爲文本打印出來了。若是不想HTML轉碼,能夠將#改爲!歎號:

- var alertData = '<script>alert(1);</script>'
p !{alertData}

//編譯出來的結果
<p><script>alert(1);</script></p>

那若是頁面就想輸出#{}和!{}呢?能夠前面加\反斜槓來讓Jade引擎不編譯變量:

p \#{alertData}
p \!{alertData}

//編譯出來的結果
<p>#{alertData}</p>
<p>!{alertData}</p>

除了用#{}和!{}外,也能夠在標籤後面緊接=等號(不轉義用!=)來輸出變量。例如:

p= alertData
p!= alertData

效果和上面是同樣的。這兩種寫法#{}和=等號輸出的區別以下:

input(value='#{aaa}')
input(value=aaa)

//編譯出來的結果
<input value="undefined">
<input>

能夠看出用#{}若是變量未定義,將會編譯成undefined做爲初始值。但用=等號來編譯變量的話,若是變量未定義就忽略。

有了變量就能輕鬆實現先後端分離。數據保存在JSON文件裏。前端用Jade模板製做頁面,在須要顯示數據處用變量來實現。例如sample.json文件裏:

{
  "charset": "UTF-8",
  "title": "My First Jade Page"
}

sample.jade文件裏:

doctype html
html
  head
    meta(charset='#{charset}')
  body
    h1.titleClass#titleID #{title}

執行命令:jade -P -w sample.jade -O sample.json後Jade文件裏的變量被自動替換。編譯出來的sample.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <h1 id="titleID" class="titleClass">My First Jade Page</h1>
  </body>
</html>

語句

Jade模板支持JavaScript語句:

  • if-else
  • unless
  • case-when
  • for-in
  • each-in
  • while

最多見的if-else:

- var author = 'Jack';
if author
  p 做者:#{author}
else
  p 無做者

//編譯出來的結果
<p>做者:Jack</p>

Jade還支持unless語句,它是if-else的反向,寫法都同樣,用的很少就不舉例了。

Jade裏的case-when語句就是JavaScript裏的switch-case語句(不知爲什麼…):

- var authors = ['Jack', 'Bill'];
case authors[0]
  when 'Jack'
    p 做者是Jack
  when 'Bill'
    p 做者是Bill
  default
    p 無做者

//編譯出來的結果
<p>做者是Jack</p>

循環遍歷用for-in(注意上面的if-else,case-when語句前不用像變量那樣加上-橫槓,但for的前面要加上-橫槓。若是漏寫-橫槓,會被解析爲標籤):

- var person = {name:'Jack', gender: 'Male'}
- for (var prop in person)
  p= person[prop]

//編譯出來的結果
<p>Jack</p>
<p>Male</p>

循環遍歷也能夠用each-in(each前的-橫槓加不加都可):

- var employee = {name:'Jack', gender: 'male'}
- each value, key in person
  p #{key}: #{value}
- var language = ['Java', 'JavaScript', 'C++']
ul
  each item in language
    li #{item}

//編譯出來的結果
<p>name: Jack</p>
<p>gender: male</p>
<ul>
  <li>Java</li>
  <li>JavaScript</li>
  <li>C++</li>
</ul>

循環遍歷也能夠用while(一樣前面加不加-橫槓都可):

- var n = 0
ul
  while n < 4
    li= n++

//編譯出來的結果
<ul>
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

Mixin

Mixin也不是個什麼新的概念,例如sass裏也用Mixin封裝css代碼,即能重用代碼,並且維護簡單。Jade也支持Mixin,能夠理解爲function,最簡單的無參數的代碼函數:

mixin sayHi
  p Hi
+sayHi

//編譯出來的結果
<p>Hi</p>

上面聲明瞭一個mixin無參函數sayHi,調用時函數名前加上+加號。如今給mixin加上參數:

mixin personInfo(name, hobbies)
  p #{name}'s hobbies:
    ul.hobby
      each hobby in hobbies
        li= hobby
+personInfo('Jack', ['movie', 'music'])

//編譯出來的結果
<p>Jack's hobbies:</p>
<ul class="hobby">
  <li>movie</li>
  <li>music</li>
</ul>

函數內天然也可調用其餘函數,例如上面兩個函數嵌套起來。這些和普通JavaScript的函數表現一致,沒啥好多介紹的:

mixin personInfo(name, hobbies)
  +sayHi
  p #{name}'s hobbies:
    ul.hobby
      each hobby in hobbies
        li= hobby
+personInfo('Jack', ['movie', 'music'])

模板

mixin能夠實現代碼的複用。文件與文件間經常使用模板來實現代碼複用。Jade用block和extends來實現模板的繼承。block塊就是定義一段HTML模塊:

block scripts
  script(src='jquery.js')
  script(src='underscore.js')
  script(src='backbone.js')  

//編譯出來的結果
<script src="jquery.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>

上面的塊名就是scripts。定義好的block後,本文件內能夠直接用block scripts來調用,這和mixin做用差很少,都能實現代碼複用。但block真正的做用在於佔位,供子文件繼承,能夠理解爲傳統OO語言裏的虛函數。父文件裏定義的block,子文件裏用extends來繼承並重寫。

例如每一個文件的頁頭都同樣,就body裏內容不同,能夠寫一個header.jade:

doctype html
html
  head
    meta(charset='#{charset}')
    block scripts
      script(src='jquery.js')
      script(src='underscore.js')
      script(src='backbone.js')
  body
    block content
      p please write content

每一個頁面的header都長這樣。而body裏定義了block content,這裏block能夠理解爲一個佔位符placeholder,須要繼承它的文件重寫block content。

根據業務需求寫頁面主體部分,例如sample.jade改爲這樣:

extends header

block content
  h1.titleClass#titleID #{title}
  a(href='http://www.jackzxl.net', target='_blank') 個人主頁
  ……

在sample.jade裏,開頭用extends代表和header.jade的繼承關係。而後根據業務重寫header.jade裏的block content。

執行jade -P -w sample.jade -O sample.json就能看到和以前如出一轍的頁面。引擎加載流程是:解析sample.jade,發現開頭有extends,就去解析header.jade,將其編譯成html。此時html裏的body裏是<p>please write content</p>。解析完header.jade就繼續解析sample.jade,發現block content,因而會將定義在header.jade裏的block content替換掉。最終輸出的是正確的頁面內容,而不是<p>please write content</p>

(但若是你執行的是jade -P -w header.jade -O sample.json會發現body裏內容爲<p>please write content</p>

除繼承外還能夠用include包含。Include會將內容無腦全拷貝進去。例如上面的sample.jade第一行extends header改爲include header。編譯出來的結果:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <script src="jquery.js"></script>
    <script src="underscore.js"></script>
    <script src="backbone.js"></script>
  </head>
  <body>
    <p>please write content</p>
  </body>
</html>
<h1 id="titleID" class="titleClass">My First Jade Page</h1>
<a href="http://www.jackzxl.net" target="_blank">個人主頁</a>

能夠看出與extends不一樣,include就是無腦將另外一個文件裏的內容直接拷貝進去,不像block + extends能夠重寫block。因此結果是錯誤的。

小細節注意:include包括extends若是省略後綴名,Jade默認該文件時.jade會進行編譯。但若是另外一個文件裏寫的是原生的html,須要寫明後綴名爲.html(例如include xx.html),明確告訴Jade不要編譯。

註釋

Jade里加上//就能添加註釋,用雙斜槓的註釋會被輸出到html源碼裏。例如:

//一行無心義的註釋

//編譯出來的結果
<!--一行無心義的註釋-->

若是不想在html源碼裏輸出註釋,用//-,在雙斜槓後加一橫槓。例如:

//-一行無心義的註釋,編譯時直接跳過該行,不會被輸出到HTML源碼裏

咱們知道html裏還能夠寫註釋型的條件語句,經常使用於兼容IE。Jade裏你一樣能夠寫這些條件語句,例如將上面header.jade改爲能識別IE89,應用不一樣的class:

doctype html
<!--[if IE 8]><html class='ie8'><![endif]-->
<!--[if IE 9]><html class='ie9'><![endif]-->
<!--[if !IE]><!--><html><!--<![endif]-->
head
  meta(charset='#{charset}')
  block scripts
    script(src='jquery.js')
    script(src='underscore.js')
    script(src='backbone.js')
body
  block content
  p please write content
</html>

上面由於有了條件語句,因此html標籤用尖括號括了起來,所以最下面要手動加上來閉合標籤。並且Jade是空格縮進敏感的,須要將原先的head和body包括裏面內容,全往前縮進2個空格。

過濾器

Jade一樣兼容其餘模塊,例如寫博客愛用的markdown,寫css愛用的less,還有coffeeScript等。只要npm安裝好後,用:冒號+模塊名就能聲明使用這些模塊,例如:

:markdown
  ...
:less
  ...
:coffee
 ...

以:markdown 爲例,會把下面塊裏的文本交給markdown去進行處理。

做者:張歆琳 連接:http://www.jianshu.com/p/e2a9cd3b7e56 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索