node.js学习笔记:jade语法

模板引擎用于生成页面,但是内容不是固定不变的,可以根据页面内容的不同进行调整。Blue的课程里主要介绍了两种模板引擎,一个是jade,另一个是ejs,全栈课程里用到的是art-template。

jade是一种“强依赖”的模板,即它无法和其他html和css文件共存,如果我们需要添加额外的非jade模板的页面代码,只能采用和jade兼容的其他模板,不能直接添加html。

jade的使用

先下载jade模块:

1
npm i jade -S

文件渲染

jade模块自带render方法,可以直接渲染模板文件。最基础的就是我们可以尝试直接在js文件里写页面内容:

1
2
3
4
5
6
7
const jade = require("jade");
let content = `
html
div
p`;
let str = jade.render(content, {pretty: true});
console.log(str);

输出结果:

image-20180815162649599

当然这种方法并不靠谱,如果文件比较复杂,js文件内会混乱不堪,我们还是用常规的单独将模板内容存在文件里的方式来操作:

  • 创建view文件夹存放模板文件
1
2
3
4
html
div
p
a
1
2
3
const jade = require("jade");
let str = jade.renderFile('view/1.jade', {pretty: true});
console.log(str);

image-20180815162951028

我们使用renderFile来读取模板文件。

jade的语法

1. 根据缩进规定层级

从上面的例子我们能看到,jade模板中根据缩进来规定元素之间的关系。如果没有缩进,那么两个元素就是平级的关系。

2. 属性放在括号()里,多个属性用逗号隔开

1
2
3
4
5
6
7
8
9
10
html
head
link(href="a.css", rel="stylesheet")
body
div
ul
li
li
li
input(type="text", id="name", value="123")

image-20180815163416718

3. 特殊属性的写法

style可以使用json写属性
1
2
3
4
5
6
html
head
link(href="a.css", rel="stylesheet")
body
div(style="width:200px;height:300px")
div(style={width: "200px",height: "300px"})

image-20180815172701406

class属性可以写成数组
1
2
3
4
html
body
div(class="active left-wrap red-bg")
div(class=["active","left-wrap","red-bg"])

image-20180815172810582

简写
  • class可以用.简写 div.active
  • id可以用#简写 div#div1
1
2
3
4
5
6
html
head
style
body
div.box
div#div1

image-20180815173132545

  • 把所有属性都放进json div&attributes({title: 'aaa', id:'div1'})

    1
    2
    3
    4
    5
    6
    html
    head
    style
    body
    div(title="aaa",id="div1")
    div&attributes({title: 'aaa', id: 'div1'})

    image-20180815173511443

4. 内容格式

  • 标签/属性后空格+内容
  • 内容不能转行
  • 嵌套内容和子标签可以共存
1
2
3
4
5
6
html
head
style
body
div aaa
span bbb

image-20180815174021302

导出jade模板内容

  • 使用fs模块,将内容写入到新的文件中

    1
    2
    3
    4
    5
    6
    const jade = require("jade");
    const fs = require("fs");
    let str = jade.renderFile('view/1.jade', {pretty: true});
    fs.writeFile('resource/1.html', str, (err) => {
    console.log(err);
    })

    image-20180815174230475

jade特色

1. 可以自动识别单双标签

  • div => <div></div>
  • Input => <input />

2. 允许自定义标签

  • 默认是双标签

    1
    2
    3
    4
    5
    6
    html
    head
    style
    body
    div
    aaa

    image-20180815174536896

    3. 原样输出内容

    1. 内容前面加|
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    html
    head
    script
    |window.onload=function (){
    | var oBtn=document.getElementById('btn1');
    | oBtn.onclick=function (){
    | alert('aaaa');
    | };
    |};
    body
    |abc
    |ddd
    |213

    image-20180815175010207

2. 标签后面加.(所有下级内容都原样输出)
1
2
3
4
5
6
7
8
9
10
11
12
13
html
head
script.
window.onload=function(){
var oBtn=document.getElementById('btn1');
oBtn.onclick=function (){
alert('aaaa');
};
};
body
|abc
|ddd
|213

image-20180815175255243

3. include文件
  • include a.js

    1
    2
    3
    4
    5
    6
    window.onload=function (){
    var oBtn=document.getElementById('btn1');
    oBtn.onclick=function (){
    alert('aaaa');
    };
    };
    1
    2
    3
    4
    5
    6
    7
    8
    html
    head
    script
    include a.js
    body
    |abc
    |ddd
    |213

    image-20180815175448912

4. 输出变量

1. 模板中:#{变量}
2. renderFile(url, {变量: 值})
1
2
3
4
html
head
body
div 我的名字:#{name}
1
2
3
const jade = require("jade");
let str = jade.renderFile('view/1.jade', {pretty: true, name: 'nikkkki'});
console.log(str);

image-20180815175803892

3. 变量可以运算
1
2
3
4
html
head
body
div 我的年龄:#{a + b}
1
2
3
const jade = require("jade");
let str = jade.renderFile('view/1.jade', {pretty: true, a:12, b: 6});
console.log(str);

image-20180815180007852

4. 变量可以是数据库获取的内容或用户输入内容
5. style和class不用花括号{},直接div(style=json)div(class=arr)
1
2
3
4
5
6
7
8
html
head
body
div(style=json)
div(class=arr)
div(class=arr class="active")
div(class=arr)
div(class=arr)
1
2
3
4
const jade = require("jade");
let str = jade.renderFile('view/1.jade', {pretty: true, json: {width: '200px', height: '200px', background: 'red'},
arr: ['aaa', 'left-wrap']});
console.log(str);

image-20180815180238159

6. style和class后面可以增加新的内容
  • div(class=arr class="active")

5. 非转义输出html标签

  • 在标签前面加!,否则<>会被转义
  • 目的:防止注入式攻击
1
2
3
4
html
head
body
div!=content
1
2
3
const jade = require("jade");
let str = jade.renderFile('view/1.jade', {pretty: true, content: "<h2>你好啊</h2><p>对方水电费色弱威尔士地方</p>"});
console.log(str);

image-20180815180914031

  • 如果直接使用变量,标签括号会被转义

    1
    2
    3
    4
    html
    head
    body
    div #{content}

    image-20180815181012690

6. jade直接编写js

1. 开头加-
1
2
3
4
5
6
html
head
body
-var a=12;
-var b=5;
div 结果是:#{a+b}

image-20180815181242202

2. 在模板输出变量
  • span = a等同于span #{a}

    1
    2
    3
    4
    5
    html
    head
    body
    span #{a}
    span=a

    image-20180815181422269

3. 循环
1
2
3
4
5
html
head
body
-for(var i=0;i<arr.length;i++)
div=arr[i]
1
2
3
const jade = require("jade");
let str = jade.renderFile('view/1.jade', {pretty: true, arr: ['aaa', 'sfasdf', '3423', 'asdfasdf']});
console.log(str);

image-20180815181657171

4. if
1
2
3
4
5
6
7
8
html
head
body
-var a=19;
if(a%2==0)
div(style={background:'red'}) 偶数
else
div(style={background:'green'}) 奇数

image-20180815181817806

5. switch
1
2
3
4
5
6
7
8
9
10
11
12
13
html
head
body
-var a=1;
case a
when 0
div aaa
when 1
div bbb
when 2
div ccc
default
|不靠谱

image-20180815181952871