nodejs實現(xiàn)myblog實例(網(wǎng)上demo參考實踐)

1纤垂、準備工作:

文本工具:VSCodeSetup-1.9.1.exe
nodejs 版本:node-v6.9.1-x64.msi
數(shù)據(jù)庫-mongodb:mongodb-win32-x86_64-2008plus-ssl-3.4.2-signed.msi

首先矾策,我們新建一個目錄 myblog,在該目錄下運行 npm init 生成一個 package.json
然后安裝 express 并寫入 package.json:
npm i express@4.14.0 --save
新建 index.js峭沦,添加如下代碼:

var express = require('express');
var app = express();

app.get('/', function(req, res) {
  res.send('hello, express');
});

app.listen(3000);

以上代碼的意思是:生成一個 express 實例 app贾虽,掛載了一個根路由控制器,然后監(jiān)聽 3000 端口并啟動程序吼鱼。運行 node index蓬豁,打開瀏覽器訪問 localhost:3000 時,頁面應(yīng)顯示 hello, express菇肃。

這是最簡單的一個使用 express 的例子地粪,后面會介紹路由及模板的使用。

1.1 supervisor
在開發(fā)過程中琐谤,每次修改代碼保存后蟆技,我們都需要手動重啟程序,才能查看改動的效果斗忌。使用 supervisor 可以解決這個繁瑣的問題质礼,全局安裝 supervisor:

npm install -g supervisor

運行 supervisor --harmony index 啟動程序,如下所示:
supervisor 會監(jiān)聽當前目錄下 node 和 js 后綴的文件织阳,當這些文件發(fā)生改動時眶蕉,supervisor 會自動重啟程序。

前面我們只是掛載了根路徑的路由控制器唧躲,現(xiàn)在修改 index.js 如下:

var express = require('express');
var app = express();

app.get('/', function(req, res) {
  res.send('hello, express');
});

app.get('/users/:name', function(req, res) {
  res.send('hello, ' + req.params.name);
});

app.listen(3000);

以上代碼的意思是:當訪問根路徑時造挽,依然返回 hello, express,當訪問如 localhost:3000/users/nswbmw 路徑時弄痹,返回 hello, nswbmw饭入。路徑中 :name 起了占位符的作用,這個占位符的名字是 name肛真,可以通過 req.params.name 取到實際的值圣拄。

小提示:express 使用了 path-to-regexp 模塊實現(xiàn)的路由匹配。
不難看出:req 包含了請求來的相關(guān)信息毁欣,res 則用來返回該請求的響應(yīng)

下面介紹幾個常用的 req 的屬性:

req.query: 解析后的 url 中的 querystring庇谆,如 ?name=haha,req.query 的值為 {name: 'haha'}
req.params: 解析 url 中的占位符凭疮,如 /:name饭耳,訪問 /haha,req.params 的值為 {name: 'haha'}
req.body: 解析后請求體执解,需使用相關(guān)的模塊寞肖,如 body-parser,請求體為 {"name": "haha"}衰腌,則 req.body 為 {name: 'haha'}

2.1 express.Router
上面只是很簡單的路由使用的例子(將所有路由控制函數(shù)都放到了 index.js)新蟆,但在實際開發(fā)中通常有幾十甚至上百的路由,都寫在 index.js 既臃腫又不好維護右蕊,這時可以使用 express.Router 實現(xiàn)更優(yōu)雅的路由解決方案琼稻。在 myblog 目錄下創(chuàng)建空文件夾 routes,在 routes 目錄下創(chuàng)建 index.js 和 users.js饶囚。最后代碼如下:

index.js

var express = require('express');
var app = express();
var indexRouter = require('./routes/index');
var userRouter = require('./routes/users');

app.use('/', indexRouter);
app.use('/users', userRouter);

app.listen(3000);

routes/index.js

var express = require('express');
var router = express.Router();

router.get('/', function(req, res) {
  res.send('hello, express');
});

module.exports = router;

routes/users.js

var express = require('express');
var router = express.Router();

router.get('/:name', function(req, res) {
  res.send('hello, ' + req.params.name);
});

module.exports = router;

以上代碼的意思是:我們將 / 和 /users/:name 的路由分別放到了 routes/index.js 和 routes/users.js 中帕翻,每個路由文件通過生成一個 express.Router 實例 router 并導(dǎo)出,通過 app.use 掛載到不同的路徑萝风。這兩種代碼實現(xiàn)了相同的功能嘀掸,但在實際開發(fā)中推薦使用 express.Router 將不同的路由分離到不同的路由文件中。

效果圖:

helloexperss.png
helloxxx.png

3.1 ejs

模板引擎有很多规惰,ejs 是其中一種睬塌,因為它使用起來十分簡單,而且與 express 集成良好歇万,所以我們使用 ejs揩晴。安裝 ejs:
npm i ejs --save
修改 index.js 如下:

index.js

var path = require('path');
var express = require('express');
var app = express();
var indexRouter = require('./routes/index');
var userRouter = require('./routes/users');

app.set('views', path.join(__dirname, 'views'));// 設(shè)置存放模板文件的目錄
app.set('view engine', 'ejs');// 設(shè)置模板引擎為 ejs

app.use('/', indexRouter);
app.use('/users', userRouter);

app.listen(3000);

通過 app.set 設(shè)置模板引擎為 ejs 和存放模板的目錄。在 myblog 下新建 views 文件夾堕花,在 views 下新建 users.ejs文狱,添加如下代碼

views/users.ejs

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      body {padding: 50px;font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;}
    </style>
  </head>
  <body>
    <h1><%= name.toUpperCase() %></h1>
    <p>hello, <%= name %></p>
  </body>
</html>

routes/users.js

var express = require('express');
var router = express.Router();

router.get('/:name', function(req, res) {
  res.render('users', {
    name: req.params.name
  });
});

module.exports = router;

通過調(diào)用 res.render 函數(shù)渲染 ejs 模板,res.render 第一個參數(shù)是模板的名字缘挽,這里是 users 則會匹配 views/users.ejs瞄崇,第二個參數(shù)是傳給模板的數(shù)據(jù),這里傳入 name壕曼,則在 ejs 模板中可使用 name苏研。res.render 的作用就是將模板和數(shù)據(jù)結(jié)合生成 html,同時設(shè)置響應(yīng)頭中的 Content-Type: text/html腮郊,告訴瀏覽器我返回的是 html摹蘑,不是純文本,要按 html 展示≡桑現(xiàn)在我們訪問 localhost:3000/users/haha衅鹿,如下圖所示:


haha.png

上面代碼可以看到撒踪,我們在模板 <%= name.toUpperCase() %> 中使用了 JavaScript 的語法 .toUpperCase() 將名字轉(zhuǎn)化為大寫,那這個 <%= xxx %> 是什么東西呢大渤?ejs 有 3 種常用標簽:

<% code %>:運行 JavaScript 代碼制妄,不輸出
<%= code %>:顯示轉(zhuǎn)義后的 HTML內(nèi)容
<%- code %>:顯示原始 HTML 內(nèi)容
注意:<%= code %> 和 <%- code %> 都可以是 JavaScript 表達式生成的字符串,當變量 code 為普通字符串時泵三,兩者沒有區(qū)別耕捞。當 code 比如為 這種字符串時,<%= code %> 會原樣輸出 烫幕,而 <%- code %> 則會顯示 H1 大的 hello 字符串俺抽。
下面的例子解釋了 <% code %> 的用法:

Data

supplies: ['mop', 'broom', 'duster']


<ul>
<% for(var i=0; i<supplies.length; i++) {%>
<li><%= supplies[i] %></li>
<% } %>
</ul>

//Result

<ul>
<li>mop</li>
<li>broom</li>
<li>duster</li>
</ul>


更多 ejs 的標簽請看 官方文檔。


3.2 includes
我們使用模板引擎通常不是一個頁面對應(yīng)一個模板较曼,這樣就失去了模板的優(yōu)勢磷斧,而是把模板拆成可復(fù)用的模板片段組合使用,如在 views 下新建 header.ejs 和 footer.ejs诗芜,并修改 users.ejs:

views/header.ejs

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {padding: 50px;font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;}
</style>
</head>
<body>

views/footer.ejs

</body>
</html>

views/users.ejs

<%- include('header') %>
<h1><%= name.toUpperCase() %></h1>
<p>hello, <%= name %></p>
<%- include('footer') %>

我們將原來的 users.ejs 拆成出了 header.ejs 和 footer.ejs瞳抓,并在 users.ejs 通過 ejs 內(nèi)置的 include 方法引入,從而實現(xiàn)了跟以前一個模板文件相同的功能伏恐。

ps:拆分模板組件通常有兩個好處:

模板可復(fù)用孩哑,減少重復(fù)代碼
主模板結(jié)構(gòu)清晰
######注意:要用 <%- include('header') %> 而不是 <%= include('header') %>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市翠桦,隨后出現(xiàn)的幾起案子横蜒,更是在濱河造成了極大的恐慌,老刑警劉巖销凑,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丛晌,死亡現(xiàn)場離奇詭異,居然都是意外死亡斗幼,警方通過查閱死者的電腦和手機澎蛛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜕窿,“玉大人谋逻,你說我怎么就攤上這事⊥┚” “怎么了毁兆?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阴挣。 經(jīng)常有香客問我气堕,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任茎芭,我火速辦了婚禮揖膜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘骗爆。我一直安慰自己次氨,他們只是感情好,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布摘投。 她就那樣靜靜地躺著,像睡著了一般虹蓄。 火紅的嫁衣襯著肌膚如雪犀呼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天薇组,我揣著相機與錄音外臂,去河邊找鬼。 笑死律胀,一個胖子當著我的面吹牛宋光,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炭菌,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼罪佳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了黑低?” 一聲冷哼從身側(cè)響起赘艳,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎克握,沒想到半個月后蕾管,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡菩暗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年掰曾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片停团。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡芬位,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出悬钳,到底是詐尸還是另有隱情匹表,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布讶坯,位于F島的核電站番电,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜漱办,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一这刷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧娩井,春花似錦暇屋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至扬霜,卻和暖如春定鸟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背著瓶。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工联予, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人材原。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓沸久,卻偏偏與公主長得像,于是被迫代替她去往敵國和親余蟹。 傳聞我的和親對象是個殘疾皇子卷胯,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容