从零开始使用nodejs+ejs模板轻松搭建web网站

什么是ejs

image.png

类比handlebarsartTemplatejade这些模板引擎等,ejs也是一个javascript模板引擎,这里就不比较它与其他模板引擎的性能做对比了,ejs语法过于朴实,如果你会写html和简单的javascript,或者你用jsx写过react,那么ejs对你来讲将轻而易举。只需简单的两步:

  1. %标签包裹的js语法写在html
  2. html后缀的文件后缀名替换成ejs
    它与node结合开发web网站简直天作之合,因为它是基于node生态的模板,只需简单的配置,即可运行在node项目中。ejs将模板与数据有效结合在一起,快速高效的构建html页面。可以将每一个ejs看做一个html或者组件来使用,具体ejs的语法使用可以查看 ejs文档

实战

第一步:使用koa来搭建一个server

首先初始化项目,在终端依次执行

1
2
csharp复制代码npm init
npm install koa

新建app.js入口文件,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
javascript复制代码const koa = require('koa')
const app = new koa()

app.use(async(ctx, next) => {
console.log(ctx.request.path)
if (ctx.request.path === '/index') { // 首页
ctx.response.status = 200
ctx.response.body = 'index'
} else if (ctx.request.path === '/hello') { // hello页
ctx.response.status = 200
ctx.response.body = 'hello world'
} else {
ctx.throw(404, 'Not found') // 404
}
await next()
})

app.listen(3000, function() {
console.log('koa应用启动!')
})

以上代码所示,根据参数ctx的获取所访问的path路径,然后分别对不同的路径进行处理

终端运行

1
复制代码npm app.js

启动koa服务看到如下效果:

20211011-160319202110111621316.gif

这是一个简单的koa项目,监听3000端开启node服务,index页面和hello页面分别展示不同的内容。第一步已经完成,接下来只需将ejs模板引擎集成到koa项目里就可以了。

第二步:集成ejs模板引擎

新建一个views目录,在此目录下放置所有的ejs模板文件,作为演示,我们先新建一个index.ejs,这时koa还不能识别ejs后缀的文件,我们需要借助app.useejs后缀的文件注册进入,将koaviews目录下的所有ejs后缀文件关联起来。

首先install一下koa-views

1
复制代码npm install koa-views

app.js内增加以下代码:

1
2
3
4
php复制代码const path = require('path')

const views = require('koa-views');
app.use(views(path.join(__dirname, './views'), { extension: 'ejs' }))

并修改以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
dart复制代码app.use(async(ctx, next) => {
console.log(ctx.request.path)
if (ctx.request.path === '/index') { // 首页
// ctx.response.status = 200
// ctx.response.body = 'index'
await ctx.render('index')
} else if (ctx.request.path === '/hello') { // hello页
ctx.response.status = 200
ctx.response.body = 'hello world'
} else {
ctx.throw(404, 'Not found') // 404
}
await next()
})

ctx.render('index')index.ejs渲染成html文件,index.ejs代码如下:

1
2
3
4
5
6
7
8
9
xml复制代码<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
</head>
<body style="overflow-y: scroll;">
<div>我是使用ejs渲染的html页面</div>
</body>
</html>

重新运行npm app.js,启动服务,重新刷新index页面,会看到ejs模板已经被编译成一个html页面,如下图:
20211011-1605572021101116274811.gif

运用在实际项目中

场景一:快速搭建web静态网站

如果需要快速建站,这个是一个不错的方案,可以使用koa,那当然也可以使用node或者express框架,因为ejs就是node生态的一部分,所以使用任意node框架都可以。在实际项目中,我们可能会用到koa-router来管理多个路由,在每个路由内render对应的ejs文件,如图所示:

image.png
demo示例

场景二:搭建一个复杂的业务型网站

以上只是介绍如何简单快速的搭建静态web网站,我们实际项目中的页面会更多更复杂,不只有静态页面,也会存在表单、列表等大批的页面需要与接口对接联调,因此也会有一些ejs模板需要做动态化处理,当然ejs模板语法也是支持的。针对如何获取动态数据,渲染动态页面,这里提供两种方案:

1、koa+ejs+MySQL(前后端不分离)

后端node服务直接连接数据库,查询数据后返回到ejs页面,根据ejs语法,我们从路由处拿到变量后渲染在ejs模板内;这时,整个node项目前后端是不分离的,node既做后端服务,又做前端渲染,如果是复杂的项目,开发人员的开发量可能比较大,当然对于全栈开发工程师或者创业型公司,这些都不在话下。

连接数据库,获取数据,后端渲染,直出页面

node示例项目中的routers/demo.js里设置demo页面的前端路由,该页面渲染了一组从数据库中直接获取的数据

1
2
3
4
5
6
7
8
9
javascript复制代码router.get('/demo', async ctx => {
console.log('连接数据库')
let result = await UserModule.find(ctx.query)
let imgs = []
result && result.filter(item => {
imgs.push(item.telephone)
})
await ctx.render('demo', { title: 'demo页面', tableData: imgs })
})

node示例项目中的views/demo.ejs内的前端代码如下:

1
2
3
4
5
6
7
8
9
10
ini复制代码<a href="/signUp">申请体验</a>
<ul style="clear: both;">
<% tableData.forEach(function(item,index){%>
<li data-id="<%= index %>" style="float: left; margin:0 10px;">
<%= index %>
<img style="width:100px" src="<%= item %>" />
<%= item %>
</li>
<% })%>
</ul>

页面效果如下图:

新标签页 - Google Chrome 2021-10-14 11-47-3520211014181106.gif
数据库中的数据如图所示:

微信截图_20211014115230.png

demo示例

表单提交调用接口

node示例项目中的routers/demo.js里设置toSingUp接口路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
csharp复制代码//接收post提交的数据
router.post('/toSingUp', async ctx => {

console.log('提交数据', ctx.request.body);
const {
telephone,
password,
companyName
} = ctx.request.body
let result = await UserModule.findUserByTelephone({
telephone
})

let isNewRecord = result && result.isNewRecord

if (isNewRecord === null) {
await UserModule.add({
telephone,
password,
companyName
})
await ctx.render('signUp', { title: '申请体验页面', message: '恭喜您,申请体验成功!' })
} else if (isNewRecord === false) {
await ctx.render('signUp', { title: '申请体验页面', message: '您已申请过,无需再申请了' })
}
})

点击demo页面内的“申请体验”进入到表单页面,当填写完表单后,点击确定,请求toSingUp接口,将表单数据存入数据库中,页面效果如下图:

20211015-183416.gif

提交的表单数据已经插入到数据库中了,如图所示:

微信截图_20211014115310.png

2、koa+ejs+request/ajax(前后端分离)

也可以在路由内使用request库(如ajaxaxioshttpfetch)第三方接口请求。拿到数据直接渲染在ejs模板内,这样的好处都是可以做到前后端开发彻底分离,可以将整个node项目交由前端,后端技术栈没有限制,前端只需调取后端接口就可以了。。这里可以分为两种方式:

  • 在后端请求第三方接口,数据直出到ejs模板
这样做的弊端很明显,就是如果接口加载过慢,会导致整个ejs页面白屏,所以采用此方案对后端接口访问速度要求较高。
  • ejs模板里直接使用ajax请求接口获取数据,然后渲染在页面
这种开发方式类似前几年的web网站开发方式(类似后端使用java开发,前端在java环境中的jsp内开发页面和联调接口),前端除了不提供后端接口服务外,其他的内容都已经涉及或者总揽,但开发方式仍然可以做到前后端分离的方式,不需要依赖后端开发环境。

我们对app.js做如下改造:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
javascript复制代码app.use(async(ctx, next) => {
console.log(ctx.request.path)
if (ctx.request.path === '/index') { // 首页
let data = ''
await requestDemo().then((body) => {
data = JSON.parse(body)
})
// ctx.response.status = 200
// ctx.response.body = 'index'
await ctx.render('index', { data })
} else if (ctx.request.path === '/hello') { // hello页
ctx.response.status = 200
ctx.response.body = 'hello world'
} else {
ctx.throw(404, 'Not found') // 404
}
await next()
})
async function requestDemo() {
let url = 'https://api.douban.com/v2/user/1000001?apikey=0df993c66c0c636e29ecbb5344252a4a'
return new Promise(function(resolve, reject) {
request(url, function(error, response, body) {
if (!error && response.statusCode == 200) {
resolve(body);
} else {
reject('接口请求失败')
}

})
});
}

我们使用request库请求第三方接口,拿到json对象data,现在可以将data中的avatarnameloc_name属性试着塞入index.ejs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
xml复制代码<div>
这里是是第三方接口<a target="_blank" href="http://www.doubanapi.com/">(豆瓣)</a>请求到的数据:
<br>
<div>
头像:
<img src="<%= data.avatar %>" />
</div>
<div>
姓名:
<%= data.name %>
</div>
<div>
地址:
<%= data.loc_name %>
</div>
</div>

localhost_3000 - Google Chrome 2021-10-13 15-29-07202110131533234.gif
demo示例

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%