模板引擎Jade

前言:node.js的模板引擎有多種,如:ejsHandlebarsjade。一開始首先學習了ejs,可是發現其有一個很大的弊端,那就是它不能繼承(因爲以前用的所有是thinkphp的模板,因此用起來很是彆扭,只能進行include,而不能extend),因而轉爲jade,將html作了一層抽象的模板引擎。php

安裝jade

利用npm全局安裝:html

$ npm install jade --global

因爲sublime對jade沒有高亮的支持,因此須要咱們手動來安裝插件,進入到sublime下的Packages,而後執行下面命令便可:node

git clone https://github.com/davidrios/jade-tmbundle.git

Hello World

先來進行一個簡單的小demo,感受下jade
新建一個文件命名爲:demo.jadeios

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,一有改變自動編譯。git

基本語法

  • jade採起的是縮進的方式來肯定其關係,而且不管是須要閉合的標籤仍是單個標籤都是用其標籤名便可,如:github

div
  h1 Hello
  br
div 
  h1 World

編譯成html就是thinkphp

<div>
  <h1>Hello</h1>
</div><br>
<div>
  <h1>World</h1>
</div>
  • 設定classid:npm

div.tite#title表明的就是<div class='title' id='title></div>'
jade中還能夠將div.tite#title簡寫爲.title#title,也會被編譯成相應的divjson

  • 設定其餘屬性:api

除了classid,其他屬性都要在括號內設定,如:

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>&lt;script&gt;alert(1);&lt;/script&gt;</div>
<div>&lt;script&gt;alert(1);&lt;/script&gt;</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與後臺交互

首先咱們須要瞭解的就是jadeAPI,詳情請見:http://jade-lang.com/api/
常常用的的API有就是jade.renderFile(filename, options)filenamejade文件的一個路徑,options是一些配置,如咱們的jade文件內變量名的值,pretty是否進行格式化等;這個函數的返回值爲html字符串

與後臺交互的一個demo:
https://github.com/zp1996/Hel...
clone下來直接node app.js就行不用npm install
本文參考:
慕課網—帶你學習Jade引擎

相關文章
相關標籤/搜索