nodejs03中间件 -3 ejs consolidate router
https://www.npmjs.com/
渲染页面(模板引擎):
前端: dom操作 虚拟dom操作 二次渲染,后期多次渲染, 优点:局部渲染
jq/js/angualrJs vue/react/....... 渲染页面(数据整合到静态页面)
后端:
抓取前端静态页面 + 渲染引擎 + 数据 返回data -> send(data)
渲染引擎: jade (所有语言)/ ejs(专门针对node) / ....
arttemplate underscore baiduTemplate mustach(前端) .......
-------------------------------------------------------------
jade|pug: 库
侵入式,强依赖
jade.renderFile('jade模板文件',{数据},{pretty:true}); 返回字符
jade模板语法
父子要缩进
属性: 标签(key=value,key2=value)
内容: 标签 内容
-------------------------------------------------------------
ejs: 模板渲染是异步的(所以有回调函数)
非侵入式,温和,弱依赖
安装+引入 ejs
ejs.renderFile('ejs模板',{数据},回调(err,data))
data == str
ejs模板 : 后缀名为ejs的html文件
ejs模板语法:
ejs 结构就是html
输出: <%= 数据名|属性名|变量名 + 表达式 %>
语句: <% 语句 %> 需要被<% %> 包裹
非转义输出: <%- 数据名|变量名 + 表达式 %>
https://www.npmjs.com/package/ejs
-------------------------------------------------------------
例子
先安装 npm i ejs jade --save
用render可以管理不同的模板引擎,
let ejs=require('ejs')
// ejs.renderFile('ejs模板',{数据},回调(err,data))
ejs.renderFile('./views/index.ejs',{},(err,data)=>{
console.log('err错误',err)//null
console.log('data渲染后的数据(str)',data)//null
})
小黑板
err错误 null
data渲染后的数据(str) <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
body{background: red}
</style>
</head>
<body>
<div >box</div>
</body>
</html>
2、
let express = require('express');
let ejs = require('ejs');
let app = express();
app.use(express.static('./public'))
app.listen(3000);
app.get('/',(req,res,next)=>{
ejs.renderFile('./views/index.ejs',{},(err,data)=>{
// console.log('err错误',err);//null
// console.log('data渲染后的数据(str)',data);//null
res.send(data)
})
})
这时候浏览器就会出现引用的ejs模板
3、
let express = require('express');
let ejs = require('ejs');
let app = express();
app.use(express.static('./public'))
app.listen(3000);
app.get('/',(req,res,next)=>{
let result = {
title:'标题',
mess:'段落',
href:'http://www.baidu.com',
m:'more',
goods:['xx1','xx2','xx3']
}
ejs.renderFile('./views/index.ejs',result,(err,data)=>{
res.send(data)
})
})
然后在ejs模板页面转义拼接
<body>
<h3><%= title %></h3>
<p><%= mess %></p>
<a href="<%= href %>"><%= m %></a>
<ul>
<% for(var i=0;i<goods.length;i++){ %>
<li><%= goods[i] %></li>
<% } %>
</ul>
</body>
//最后在页面就会呈现拼接的结果
consolidate 管理多个模板引擎 consolidate
安装: npm i consolidate -S
注意: ejs 需要安装,但无需引入
app.set('view.engine','html'); 模板最终 输出类型设置
app.set('views','./views'); 引擎模板目录设置
app.engine('html',consolidate.ejs); 输出与引擎匹配
app.engine('css',consolidate.jade); 输出与引擎匹配
渲染API:
res.render('模板文件名',{数据}) 整合页面和数据,完成渲染,发往浏览器
###例子
先安装consolidate
npm i consolidate --S
可以直接把上面的改为
let app = express();
app.use(express.static('./public'))
app.listen(3000);
app.engine('html', consolidate.ejs);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
app.get('/',(req,res,next)=>{
let result = {
title:'标题',
mess:'段落',
href:'http://www.baidu.com',
m:'more',
goods:['xx1','xx2','xx3']
}
res.render('index.ejs',result)
})
路由
路由(router): 告诉你去哪
前端:导向 路由就告诉你应该去哪
后端: 子服务 一个路由就是一个小的服务(server/app)
1. 创建路由
router = express.Router(); 返回路由对象
2. 导出路由
module.exports = router;
3. 安装路由
app.use('地址',router);
router.use('地址'子router) 需要next 延续
4. 路由处理响应:
router.响应API(地址, 处理函数)
router.get('/',fn)
router.post('/1',fn)
router.all('*',当前router路由下的验证工作) 需要next 延续
-----------------------------------------------------------------
例子
let express = require('express');
let app = express();
app.listen(3000);
app.use(express.static('./public'))
//一堆接口,全部路由分发
let routerA = require('./routes/a');
app.use('/a',routerA)
//访问a或者a下面所有的请求时,实际都交给了routerA
app.use('/b',require('./routes/b.js'))
//实际上是把主服务留在这里,下面的细小的服务拆分了出去
在routes下面a.js文件内
let express = require('express')
let router = express.Router();
router.get('/',(req,res,next)=>{console.log('/a')})
router.use('/aa',require('./aa/aa'))
module.exports=router;
在routes下面b.js文件内
let express = require('express')
let router = express.Router();
//b的处理
router.get('/',()=>{
console.log('/b');//里面的"/"===外面的"/b"
})
module.exports=router;
在routes文件夹下有aa文件夹,内部aa.js文件内
let express = require('express')
let router = express.Router();
router.all('/*',(req,res,next)=>{
//处理当前层级路由的公共业务
res.bulala='labula'
next()
})
router.get('/',(req,res,next)=>{console.log('/a/aa',res.bulala)})
router.get('/a1',(req,res,next)=>{console.log('/a/aa/a1',res.bulala)})
router.get('/a2',(req,res,next)=>{console.log('/a/aa/a2',res.bulala)})
module.exports=router;
搭配环境
//http querystring url fs path
//body-parser cookie-session multer express
//ejs jade consolidate
//router
let express = require('express');
let bodyParser = require('body-parser');
let cookieSession = require('cookie-session');
let multer = require('multer')
let consolidate = require('consolidate')
//1.web服务器
let app = express();
app.listen(3000)
//2.资源托管
app.use(express.static('./public'))
// app使用系统自带的中间件
//3.获取body数据
app.use(bodyParser())
//4.用户唯一性判断
app.use(cookieSession({
name:'alex_id',
keys:['aa','bb'],//sha1加密一种轮询方式
maxAge: 1000 * 60 * 60 * 24 * 15
}))
//5.接受客户端上传的文件
let upload = new multer({dist:'./public/uploads'})
app.use(upload.any())
//6. 使用一部分的后端渲染
app.engine('html', consolidate.ejs);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
//7. 拆分node服务
app.use('/',require('./routes/root'))