截圖:javascript
這個項目的數據是根據以前瓜子網爬蟲爬的北京區數據css
express + mongodb + pug(jade) + flex.css:html
項目地址: https://github.com/uustoboy/guazi-pugjava
項目截圖:node
目錄說明:git
|---app.js ----------------------node啓動文件 |---gulpfile.js------------------gulp自動化重啓 |---models-----------------------mongodb的models |---node_modules-----------------node依賴 |---package.json-----------------包描述文件及開發者信息 |---public-----------------------靜態文件(css/js/img) |-----c--------------------------css目錄 |-----j--------------------------js目錄 |---routers----------------------路由 |---schemas----------------------mongodb的schemas |---views------------------------視圖模板
package.json:github
{ "name": "guazi-pug", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "body-parser": "^1.16.0", "express": "^4.14.1", "gulp": "^3.9.1", "gulp-nodemon": "^2.2.1", "mongoose": "^4.8.1", "pug": "^2.0.0-beta11" } }
node app.js 啓動文件ajax
1.加載express 用到的模塊mongodb
2.設置靜態文件的託管、模板的引擎數據庫
3.在把路由文件加載到啓動頁
4.鏈接已經運行的mongodb
項目啓動
1 "use strict"; 2 3 var express = require('express'); //引入express; 4 var mongoose = require('mongoose'); //引入mongoose; 5 var app = express(); 6 7 //加載body-parser,用來處理post提交過來的數據 8 var bodyParser = require('body-parser'); 9 10 //bodyparser設置 11 app.use( bodyParser.urlencoded({extended: true}) ); 12 13 //設置靜態文件託管 14 app.use( '/public', express.static( __dirname + '/public') ); 15 16 //設置模板文件存放的目錄,第一個參數必須是views,第二個參數是目錄 17 app.set('views', './views'); 18 19 //設置模板引擎 20 app.set('view engine', 'pug'); 21 22 //加載路由; 23 app.use('/', require('./routers/api')); 24 app.use('/', require('./routers/car-routers')); 25 26 //監聽http請求 27 mongoose.connect('mongodb://localhost/car', function(err) { 28 if (err) { 29 console.log('數據庫鏈接失敗'); 30 } else { 31 console.log('數據庫鏈接成功'); 32 app.listen(3000); 33 } 34 });
schemas/car-schemas.js 定義這個集合的數據類型:
1 "use strict"; 2 var mongoose = require('mongoose'); 3 4 //分類的表結構 5 module.exports = new mongoose.Schema({ 6 info:String, //車; 7 money:String, //價錢; 8 phone:String, //電話號碼; 9 time:String, //上牌時間; 10 mileage:String, //千米數; 11 gearbox:String, //變速箱; 12 emission:String, //排放標準; 13 location:String, //上牌地; 14 imgs:Array //圖片; 15 });
models/car-models.js 集合和數據庫鏈接起來同時能夠操做:
1 "use strict"; 2 var mongoose = require('mongoose'); 3 var carSchema = require('../schemas/car-schemas.js'); 4 5 module.exports = mongoose.model('sell_carinfos', carSchema);
routers/car-routers.js 請求路徑的路由匹配:
1.router.get('/') 匹配index頁面
2.router.get('/:id') 匹配詳情頁是有詳情id
3.router.get('*') 匹配的是404錯誤頁
1 "use strict"; 2 var express = require('express'); 3 var router = express.Router(); 4 5 var carUser = require('../models/car-models'); 6 var data; 7 8 //匹配 汽車詳情 9 router.get('/:id', function(req, res, next) { 10 11 var _id = req.params.id || ''; 12 13 //根據id查找數據; 14 carUser.findOne({ _id : _id},function( err,contents ){ 15 16 if( err ){ 17 18 next(); 19 20 }else{ 21 22 res.render('./info',{ 23 carinfo : contents 24 }); 25 26 } 27 28 }); 29 30 }); 31 32 //主頁面; 33 router.get('/', function(req, res, next) { 34 35 var limit = 8;//查幾條; 36 var skip = 0; //從第幾條開始; 37 //查表 38 carUser.find({}).limit(limit).skip(skip).then(function( contents ){ 39 res.render('./index',{ 40 carlists : contents 41 }); 42 }); 43 44 }); 45 46 // 404 47 router.get('*', function(req, res){ 48 res.render('./404') 49 }); 50 51 module.exports = router;
routers/api.js 處理像$.ajax請求 單獨的路由:
"use strict"; var express = require('express'); var router = express.Router(); var carModels = require('../models/car-models.js'); //統一返回格式 var responseData = {}; //翻頁; router.post('/pages', function(req, res, next) { var pages = req.body.pages || 0; //頁碼; var limit = 8; //取幾條數據; var skip = limit * pages; //從第幾條開始; var totalPages = 0; //總頁數; carModels.find({}).count({},function(err,count){ if(err){ console.log('出錯了'); } totalPages = Math.floor( count / limit ); }); carModels.find({}).limit(limit).skip(skip).then(function(data) { if( pages < totalPages ){ responseData.code = 1; responseData.message = data; return res.json(responseData); }else{ responseData.code = 2; return res.json(responseData); } }); }); module.exports = router;
views/layout.pug 公共頭文件 提出共同的css和js:
1 doctype html 2 html 3 head 4 meta(charset="UTF-8") 5 meta(name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0") 6 title 瓜子二手車 7 link(rel="stylesheet" type="text/css" href="/public/c/flex.css") 8 link(rel="stylesheet" type="text/css" href="/public/c/index.css") 9 link(rel="stylesheet" type="text/css" href="/public/c/dropload.css") 10 script(src="/public/j/zepto.min.js" type="text/javascript") 11 body 12 block content
views/index.pug 列表頁 繼承layaout 同時處理傳過json綁定在頁面上:
extends layout block content ul.car-ul each car in carlists li a(href=car._id flex) div(class="car-img" flex-box="1") img(src=car.imgs[0]) div(class="car-infolist" flex-box="9") div(class="car-infolist" flex-box="9") div.car-name. #{car.info} div.car-km span. #{car.time}年/#{car.mileage}萬千米 div.car-price strong. #{car.money}萬 script(src="/public/j/dropload.min.js" type="text/javascript") script(src="/public/j/index.js" type="text/javascript")
views/info.pug 繼承layaout 詳情頁:
1 extends layout 2 3 block content 4 div.product-head 5 img(class="product-headImg" src=carinfo.imgs[0]) 6 div 7 h1.product-title #{carinfo.info} 8 div.sevser-about 9 ul(class="mod-sev" flex) 10 li(flex="main:center cross:center" flex-box="1") 11 div 12 p.about-own. 13 車主報價 14 p.about-prize. 15 #{carinfo.money}萬 16 li(flex="main:center cross:center" flex-box="1") 17 div 18 p.about-own. 19 貸款首期款 20 p.about-prize. 21 ¥#{ Math.floor(parseFloat( carinfo.money.substring(1,carinfo.money.length) ) * 0.3) }萬 22 li(flex="main:center cross:center" flex-box="1") 23 div 24 p.about-own. 25 服務費 26 p.about-prize. 27 #{ Math.floor(parseFloat( carinfo.money.substring(1,carinfo.money.length) ) * 0.03 *10000) }元 28 div.column 29 div.column-head. 30 基本信息 31 ul(flex class="column-carul") 32 li(flex-box="5") 33 span.info-title. 34 表顯里程: 35 span #{carinfo.mileage}萬千米 36 li(flex-box="5") 37 span.info-title. 38 上牌時間: 39 span #{carinfo.time} 40 li(flex-box="5") 41 span.info-title. 42 牌照歸屬: 43 span #{carinfo.location} 44 li(flex-box="5") 45 span.info-title. 46 排放標準: 47 span #{carinfo.emission} 48 li(flex-box="5") 49 span.info-title. 50 變速箱: 51 span #{carinfo.gearbox} 52 li(flex-box="5") 53 span.info-title. 54 看車地址: 55 span #{carinfo.location} 56 div.product-img 57 each imgs in carinfo.imgs 58 img(src=imgs)
gulp node app.js的自動重啓
1 'use strict'; 2 3 var gulp = require('gulp'); 4 var nodemon = require('gulp-nodemon'); 5 6 gulp.task('start', function () { 7 nodemon({ 8 script: 'app.js' 9 , ext: 'js html' 10 , env: { 'NODE_ENV': 'development' } 11 }) 12 }) 13 14 //執行的默認事件; 15 gulp.task('default',function(){ 16 gulp.run('start'); 17 });
後記:
麻雀雖小五臟俱全~
參考資料:
express : http://www.expressjs.com.cn/
pug : https://pugjs.org/api/getting-started.html
mongodb : http://www.runoob.com/mongodb/mongodb-tutorial.html
mongoose: http://www.nodeclass.com/api/mongoose.html
------------------------------------------------------------------------------------------------------------------
scott : http://www.imooc.com/learn/259 (jade模板講解)
scott : http://www.imooc.com/learn/75 || http://www.imooc.com/learn/197 (express建站)
狼族小狽 : https://github.com/lzxb/flex.css (flex.css)
西門 : https://github.com/ximan/dropload (滑動下拉加載JS插件)