Pug快速入门
Pug快速入门
参考文档:
¶什么是PUG?
PUG原名JADE,是一个高性能html语言模板引擎,用于Node.js和浏览器环境,使用JavaScript实现。pug不仅功能强大,最重要的是它真的非常简单,只需要一点html和 javascript基础就能在一小时内上手使用。pug学习成本极低、效率高、功能强大的特点得到了众多开发者的喜爱。
¶原生html存在的痛点
- 纯静态,没有动态变量的概念
- 不能复用,没有组件概念,每个页面对应一个html文件
- 当html结构较深,代码多的时候或者没有规范的换行缩进会使代码看的十分杂乱,让人摸不着头绪,难以维护和排查问题
¶pug的特点
而Pug是简洁、对空格敏感的语法,抛弃了原生html尖括号和闭合标签,使用换行+缩进来表示嵌套关系,让你在写html时也像写python代码一样流畅自然!
以下是pug官网的一个简单示例:
doctype html
html(lang="en")
head
title= pageTitle
script(type='text/javascript').
if (foo) bar(1 + 5);
body
h1 Pug - node template engine
#container.col
if youAreUsingPug
p You are amazing
else
p Get on it!
p.
Pug is a terse and simple templating language with a
strong focus on performance and powerful features.
pug将上述代码转换为:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Pug</title>
<script type="text/javascript">
if (foo) bar(1 + 5);
</script>
</head>
<body>
<h1>Pug - node template engine</h1>
<div id="container" class="col">
<p>You are amazing</p>
<p>
Pug is a terse and simple templating language with a strong focus on
performance and powerful features.
</p>
</div>
</body>
</html>
对比之下可以看到,PUG的优势在于其语法的简洁性,省去了html的闭合标签,通过换行缩进来表示嵌套关系,极大的减少了代码量,并且,pug有其自己的语法,拥有循环、条件控制、定义变量、代码块复用等功能。可以说当你在写pug模板的同时,也在写Javascript,当你习惯了其语法规则后,可以显著提升你编写html代码的效率。
¶Pug十分钟上手
在本章,我们先对Pug的语法特点进行精炼的介绍,点出其与javascript语言以及原生html语言的不同之处,关于pug语法的详细教程可能在后面分章节更新~
¶使用Javascript
Pug 为您在模板中嵌入 JavaScript 提供了可能。主要有三种类型的代码。
- 用
-
开始的行不直接进行输出的代码,可以在这行执行javascript 表达式 =
开始的行表示带有输出的代码,它应该是可以被求值的一个 JavaScript 表达式,为安全起见,它将被 HTML 转义。- 用
!=
开始的行代表不转义的,带有输出的代码。这将不会做任何转义,所以用于执行用户的输入将会不安全
编译前:
- for (var x = 0; x < 3; x++)
li item
p= '这个代码被 <转义> 了!'
p!= '这段文字' + ' <strong>没有</strong> 被转义!'
编译后:
<li>item</li>
<li>item</li>
<li>item</li>
<p>这个代码被 <转义> 了!</p>
<p>这段文字 <strong>没有</strong> 被转义!</p>
¶变量
在Pug中,你可以使用-var
来声明一个变量,且无需考虑变量类型,类似于原生JavaScript中的声明变量。你可以在该变量的作用域内任意使用此变量,包括赋值、修改、引用、传参等等。
在Pug中,每一格缩进就代表一个新的作用域,作用域之间存在上下级关系,其机制基本与java、python等常用语言相同,你可以获取同级或上级作用域中的变量,但是无法获取子作用域的变量。通过下面这个例子,相信你可以很快理解Pug中的变量及作用域问题。
var a = 1
var b = 2
var c = 3
body
-let d = 4 // d是处于body 作用域内的变量,和他同级或它的子级可以找到他
div
p=d // 可以从上层作用域找到d
p=a // 可以从顶级作用域找到a
p=e // undefined 不会输出任何内容 与JS相同,e还没有被赋值
- var e = 5
ul
while e > 0 // 这里会迭代5次, 产生5个作用域
- e--
- const f = 10 + e // f是 while循环语句作用域的变量 上层作用域拿不到它
li = f
¶属性Attribute
标签属性和 HTML 语法非常相似。
- 你可以用空格、逗号、逗号+空格三种方法作为属性分隔符,或者将多个属性换行写。
- 属性的值可以是所有的JavaScript表达式
- 类可以使用
.classname
语法来定义 - ID可以使用
#idname
来定义
¶不同的属性分隔方法
编译前:
a(href='baidu.com') 百度
a(class='button' href='baidu.com') 百度
a(class='button', href='baidu.com') 百度
//所有的javascript表达式都能使用
- var authenticated = true
body(class=authenticated ? 'authed' : 'anon')
//多行属性
input(
type='checkbox'
name='agreement'
checked
)
//不转义的属性
div(escaped="<code>")
div(unescaped!="<code>")
编译后:
<a href="baidu.com">百度</a>
<a class="button" href="baidu.com">百度</a>
<a class="button" href="baidu.com">百度</a>
<body class="authed"></body>
<input type="checkbox" name="agreement" checked="checked" />
<div escaped="<code>"></div>
<div unescaped="<code>"></div>
¶类属性
类可以使用 .classname
语法来定义,考虑到使用 div
作为标签名这种行为实在是太常见了,所以如果您省略掉标签名称的话,div
就是默认值:
编译前:
a.button(href="baidu.com")
.content
编译后:
<a class="button" href="baidu.com"></a>
<div class="content"></div>
¶ID属性
D 可以使用 #idname
语法来定义,与class相同,考虑到使用 div
作为标签名这种行为实在是太常见了,所以如果你省略掉标签名称的话,div
就是默认值:
编译前:
a#main-link(href="baidu.com")
#content
编译后:
<a id="main-link" href="baidu.com"></a>
<div id="content"></div>
¶条件控制与迭代
pug的条件控制与迭代与JavaScript很相似,你可以省略掉开头的-
,效果是相同的。
¶if-else语句
编译前:
- var user = { description: 'foo bar baz' }
- var authorised = false
#user
if user.description
h2.green 描述
p.description= user.description
else if authorised
h2.blue 描述
p.description.
用户没有添加描述。
不写点什么吗……
else
h2.red 描述
p.description 用户没有描述
编译后:
<div id="user">
<h2 class="green">描述</h2>
<p class="description">foo bar baz</p>
</div>
¶条件分支case
case
也就是JavaScript语句中的switch
,在case
语句中,可以像 JavaScript 中的 switch
语句那样使用传递(fall through)。不同之处在于,在 JavaScript 中,传递会在明确地使用 break
语句之前一直进行。而在 Pug 中则是,传递会在遇到非空的语法块前一直进行下去。在某些情况下,如果您不想输出任何东西的话,您可以明确地加上一个原生的 break
语句:
编译前:
- var friends = 0
case friends
when 0
when 1
p 您的朋友很少
default
p 您有 #{friends} 个朋友
编译后:
<!-- 这里发生了传递! -->
<p>您的朋友很少</p>
¶迭代
Pug 目前支持两种主要的迭代方式: each
和 while
。这里主要介绍each
,这是Pug头等的迭代方式,功能十分强大,最推荐使用。当然while
也常用于创建一个简单循环。
在Pug中,你可以很方便的获取迭代对象的索引和键值:
编译前:
ul
each val in [1, 2, 3, 4, 5]
li= val
ul
each val, index in ['〇', '一', '二']
li= index + ': ' + val
ul
each val, index in {1:'一',2:'二',3:'三'}
li= index + ': ' + val
编译后:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<ul>
<li>0: 〇</li>
<li>1: 一</li>
<li>2: 二</li>
</ul>
<ul>
<li>1: 一</li>
<li>2: 二</li>
<li>3: 三</li>
</ul>
用于迭代的对象或数组仅仅是个 JavaScript 表达式,因此它可以是变量、函数调用的结果,又或者其他的什么东西。您还能添加一个 else
块,这个语句块将会在数组与对象没有可供迭代的值时被执行。下面这两个例子的作用是等价的:
编译前:
- var values = [];
ul
each val in values.length ? values : ['没有内容']
li= val
//与上面的例子等价
- var values = [];
ul
each val in values
li= val
else
li 没有内容
编译后:
<ul>
<li>没有内容</li>
</ul>
¶结语
看到这里,你应该已经对Pug语言有了一定的了解了,现在你应当理解为什么之前会说写Pug就像写JavaScript一样了,因为它们真的很像!你可以随意的使用变量声明与条件控制语句,相当于同时在编写Html和JavaScript代码,