express 实践
截图:
这个项目的数据是根据之前瓜子网爬虫爬的北京区数据
express + mongodb + pug(jade) + flex.css:
项目地址: https://github.com/uustoboy/guazi-pug
项目截图:
目录说明:
|---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:
{ "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 启动文件
1.加载express 用到的模块
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插件)