上一节做了对Express做了简单的介绍,提出了controller,介绍了路由。这一节将重点放到视图和模型上,完成几个静态页面并部署到heroku上。
导航
前端布局使用bootstrap,从官网下载后置于public文件夹下。打开layout.jade 先做一个导航.
doctype html html head meta(name=\'viewport\', content=\'width=device-width, initial-scale=1.0\') title= title link(rel=\'stylesheet\', href=\'/bootstrap/css/bootstrap.css\') link(rel=\'stylesheet\', href=\'/stylesheets/style.css\') body nav.navbar.navbar-default.navbar-fixed-top.navbar-inverse .container .navbar-header a.navbar-brand(href=\'/\') ReadingClub .collapse.navbar-collapse ul.nav.navbar-nav.pull-right li a(href=\'/\') 首页 li a(href=\'/Books\') 读物 li a(href=\'/About\') 关于 li a(href=\'/Register\') 注册 li a(href=\'/Login\') 登录 #bodycontent.container block content footer.container .row .col-xs-12 small © stoneniqiu 2016 script(src=\'/javascripts/jquery-1.11.1.min.js\') script(src=\'/bootstrap/js/bootstrap.min.js\')
block content 上文有介绍,可以理解成一个占位符。因为现在还用不惯stylus,就直接写css了,这样vs还有智能提示。
style.css
运行起来,看到导航条
如果访问注册和登录,因为之前没有设置相应的页面就会报404。
app.use(function (req, res, next) { var err = new Error(\'Not Found\'); err.status = 404; next(err); });
回头看layout.jade 没有一个html标签,直接是元素名或者样式名称开始,这种写法和sublime中写html相似,属性写在括号里,文字内容用空格隔开。元素的嵌套关系 通过严格的缩进来控制,这样的好处是代码量更少,层次更分明,但是代码一长,很不容易判断缩进的准确位置,没对齐很容易造成意外的嵌套。我现在的经验是从左往右的编写,而不是从上往下编写。也就是说,用jade写html的时候,先写好最外层的元素,然后在逐步写里面的子元素。而不是从上往下一个一个的写,这样就会出现缩进来带的困扰。
模型与视图
回到home.js,我们用JavaScript建立一个books模型,包含title,info,rating,img和tags。因为还没有使用数据库,这里直接创建。
books:
res.render(\'books\', { title: \'Books\', books: books });
在home.js中加入books,模型其实就是一个json对象,接下来我们修改books页面的布局。这里用左右布局,稍加调整,
extends layout block content .row .col-md-9.page each book in books .row.booklist .col-md-2 img(src=\'#{book.img}\') .col-md-10 p a(href="/Detail/#{book.id}")=book.title p=book.info p - for (var i = 1; i <= book.rating; i++) span.glyphicon.glyphicon-star - for (i = book.rating; i < 5; i++) span.glyphicon.glyphicon-star-empty p.tags each tag in book.tags span=tag .col-md-3 .userinfo p stoneniqiu
得到效果:
当然这些都还是静态的,接下来介绍下jade引擎。jade是一个高性能的模板引擎,用于node。
1.母版页
借助bootstrap的栅栏布局,分成左右两部分。extends layout 表示引入layout母版页,而layout中的block content 就会被当前页面的block content中的内容替换掉。同样可 以定义多个block
//- layout.jade doctype html html head block title title Default title body block content
引用页面:
//- index.jade extends layout block title title Article Title block content h1 My Article
生成的html:
<!doctype html> <html> <head> <title>Article Title</title> </head> <body> <h1>My Article</h1> </body> </html>
2.循环
each book in books
表示循环输出模型,在Asp.net MVC的视图中,需要先定义Model的类型。jade省掉了这个model,直接获取模型的属性。同样也支持for循环,前面的‘-’号不可少。
- for (var i = 1; i <= book.rating; i++) span.glyphicon.glyphicon-star - for (i = book.rating; i < 5; i++) span.glyphicon.glyphicon-star-empty
3.赋值
空格赋值,这个空格不能少,不然jade会把ptext视为一个元素。空格后方都认为是字符串。
p text 输出 <p>text<p>
所以如果是输出变量,一定要用‘=’赋值。
a(href="/Detail/")=book.title
但如果是字符串组合输入,应该用#{}
img(src=\'#{book.img}\') p 读过#{book.title}
如果不想转义内容 !{},- var 表示定义变量 ,相当于Razor中的@{}
- var riskyBusiness = "<em>Some of the girls are wearing my mother\'s clothing.</em>"; .quote p Joel: !{riskyBusiness}
输出
<div class="quote"> <p>Joel: <em>Some of the girls are wearing my mother\'s clothing.</em></p> </div>
4.属性
如果是增加元素属性,则更在元素后面的括号里完成
a(href="/Detail/")=book.title
输出:
<a href="/Detail/">深入浅出Node.js</a>
如果是多个属性用逗号隔开,也可以换行
a(class=\'button\', href=\'google.com\') input( type=\'checkbox\' name=\'agreement\' checked )
还可以加入表达式
- var authenticated = true body(class=authenticated ? \'authed\' : \'anon\')
而Razor要在元素里面写表达式就有点丑陋。
@{ var ischeck = true; } <input type="checkbox" @if (ischeck) { @Html.Raw("class=\'selected\'") } />
5.子视图
这里用子视图还不太准确,我们已经知道通过extends 和 block 来引入母版页,并按模块取代内容。而子视图主要是强调复用,是嵌入到别的视图文件中。jade是用mixin(混合)定义一个部分视图,用‘+’使用 例如:
mixin list ul li foo li bar li baz +list +list
输出
比如把页面上显示星星的部分提出来,在view文件夹下建一个_include文件夹,并创建一个rating.jade文件:
mixin outputRating(rating) - for (var i = 1; i <= rating; i++) span.glyphicon.glyphicon-star - for (i = rating; i < 5; i++) span.glyphicon.glyphicon-star-empty
这样在页面上引用
include _includes/rating
然后在指定位置输出,主要有‘+’号。
p +outputRating(book.rating)
同理创建了detail.jade 和index.jade
detail.jade
index.jade
至此,我们创建了三个静态页面,基本熟悉了jade语法。当然jade不止这些,后期随着项目的深入再不断的探索。
部署:
目前我已经将代码提交到github上,然后部署在heroku上。
github:https://github.com/stoneniqiu/ReadingClub 有兴趣的朋友可以一起开发学习。
观摩请戳:https://stoneniqiu-mean.herokuapp.com/
heroku提供了三百兆的免费空间,还有个规则的域名,如何部署请移步:三步将Node应用部署到Heroku上
jade官网:http://jade-lang.com/
理想就是自己喜欢做,并对社会和他人都有意义的事情!