热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

EJS学习指南

基本概念ejs的基本概念十分简单,一个html模板+数据,和传统的php字符串模板拼接非常相似.例如我们有一个列表该列表展示一组新闻,理想中的状态如下:新

基本概念

ejs的基本概念十分简单,一个html = 模板 + 数据,和传统的php字符串模板拼接非常相似.

例如我们有一个列表该列表展示一组新闻,理想中的状态如下:


新闻1


新闻2


新闻3


新闻4


新闻5


如果数据是异步获取的,我们可以利用for循环拼接字符串来实现内部的多个h2然后再追加到html中.

let data = [],result = '';for (i=0,len = data.length;i>';}

但是ejs更像是如下的样子(伪代码):

/**
* @param {string} template 字符串模板
* @param {object} data 模板需要的数据
*/
function ejs(template,data) { return template(data);
}

也就是说ejs需要一个字符串模板,和一个data也就是我们的数据源.

template是字符串模板基于html语法但是ejs提供了特殊符号用于控制我们传入的数据如何填充到html中.

安装

这里就不提及了你可以去官网下载也可以使用npm进行安装.

我使用的版本是2.6.1是目前的最新版本,网上的很多文章实际上有些已经过时了,因为API有些变动.

ejs中文文档中有较新的API一览.

使用

ejs分为两个版本一个是CommonJs版本,另外一个是AMD规范的版本.

后面的测试基本都是在浏览器中运行,我没有使用requireJs直接使用script引入的ejs:

ejs会将自身挂载到window对象上,所以你只要console.log(ejs)控制台有输出就说明安装成功了.

渲染单个数据

ejs.render('

<%= data %>

',{data:123});

返回:

123

render方法只需要两个参数,和之前说的一样第一个为模板字符串,而二个为数据源.

ejs使用html作为模板的基础语言,所以你不需要进行学习任何额外的语法,需要了解的就是ejs给我们提供的几个模板语法.

那么<%= %>目前看来就是输出数据,ejs所做的仅仅是用123来替换掉<%= data %>而已.

渲染多个数据

在ejs提供的语法中可以直接使用Javascript所以你可以非常容易理解使用复杂逻辑如何完成渲染的,我们来看一个具体的例子:

const template = `


<% news.forEach(item=>{ %>

<%= item %>


<% }) %>

`;
const data = {
news:['新闻1','新闻2','新闻3']
};
const htmlString = ejs.render(template,data);

返回的内容:

新闻1

新闻2

新闻3

实际上去除掉ejs提供了模板语法,内容就是这个样子的:

news.forEach(item=>{
'

'+item+'

'
})

也就是说<% %>的符号不会产生实际的输出,但是可以放置Javascript代码用于控制中间代码块的执行流程.

有条件的渲染数据

const template = `


<% data.forEach(item=>{ %>
<% if(item.sexCode){ %>

<%= item.name+'的性别是女' %>


<% } else { %>

<%= item.name+'的性别是男' %>


<% } %>
<% }) %>

`;
const data = {
data:[
{
name:'小明',
sexCode:0
}
,
{
name:'小红',
sexCode:1
}
]
};
const htmlString = ejs.render(template,data);

输出:


小明的性别是男



小红的性别是女


这个例子稍显复杂,但是他告诉我们几点有价值的内容:

  • <% %>用于存放Javascript代码片段是确定无疑的事情了,甚至在这个例子中我们还执行了嵌套操作.
  • <%= %>实际上把内容当作表达式执行后再输出的,至少它有执行表达式的能力

本质

  • <% %>用于执行其中的Javascript代码
  • <%= %>会对其中的Javascript代码html转译

其他的模板语法

这里我就将官网的一览贴了过来然后每个提供一个例子:

  1. <% &#8216;脚本&#8217; 标签,用于流程控制,无输出。
  2. <%_ 删除其前面的空格符
  3. <%= 输出数据到模板(输出是转义 HTML 标签)
  4. <%- 输出非转义的数据到模板
  5. <%# 注释标签,不执行、不输出内容
  6. <%% 输出字符串 &#8216;<%&#8217;
  7. %> 一般结束标签
  8. -%> 删除紧随其后的换行符
  9. _%> 将结束标签后面的空格符删除

先看一下2,8,9这三个.

之前我的几个例子中包含了很多空格和换行原因是因为使用的是默认的输出格式,例如我们之前使用这个例子:





小明的性别是男





小红的性别是女





来看一下修改后的效果.

使用删除空格符号:


<%_ data.forEach(item=>{ _%>
<%_ if(item.sexCode){ _%>

<%= item.name+'的性别是女' _%>


<%_ } else { %>

<%= item.name+'的性别是男' _%>


<%_ } _%>
<%_ }) _%>

输出的内容:



小明的性别是男


小红的性别是女



可以看到确实少了一些内容,但是实际上空隙是由换行符号引起的,这次我们来删除尾部的换行符号:


<% data.forEach(item=>{ -%>
<% if(item.sexCode){ -%>

<%= item.name+'的性别是女' -%>


<% } else { -%>

<%= item.name+'的性别是男' -%>


<% } -%>
<% }) -%>

输出的内容:



小明的性别是男



小红的性别是女



虽然行数减少了不过格式乱掉了.

注意:如果不想保留换行和空格可以把方法的选项参数中的rmWhitespace设置为true.

<%- %>的使用

默认情况下在<%= %>之间的html字符串会被做转译处理:

<%= '

hello world

' %>

返回:

hello world

使用<%- %>:

该模板语法不会转译html字符串

<%- '

hello world

' %>

返回:

hello world

<%# %>的使用

该标签不会在最终的结果中出现,作为模板中的注释:

<%# '

hello world

' %>

返回的结果:

<%% %>的使用.

该操作返回的是模板字符串(string):

<%% if(id){ %>
<%% } %>

返回的结果:

<% if(id){ %>
<% } %>

API

ejs渲染的API主要有三个分别是:

  • compile(str, options)
  • render(str, data, options)
  • renderFile(filename, data, options,callback(err,str)) 在浏览器端无效

区别是:

  • render 传入模板字符串和数据返回结果
  • compile 返回一个模板函数,对这个函数传入数据获取结果
  • rednerFile 从文件中获取模板

ejs内部是有缓存系统的它会将模板字符串解析为一个数据结构后续的操作将不会在此解析模板.

compile就是返回了内部已经处理好模板字符串的函数,在有大量数据重复使用这套模板的时候就会带来性能提升,而对于renderrenderFile来说需要在选项中设置cachetrue,对于render方法还需要指定filename选项.

选项参数

这里也是照搬官网的:

  1. cache 缓存编译后的函数,需要提供 filename
  2. filename 被 cache 参数用做键值,同时也用于 include 语句
  3. context 函数执行时的上下文环境
  4. compileDebug 当为 false 时不编译调试语句
  5. client 返回独立的编译后的函数
  6. delimiter 放在角括号中的字符,用于标记标签的开与闭
  7. debug 将生成的函数体输出
  8. _with 是否使用 with() {} 结构。如果为 false,所有局部数据将存储在 locals 对象上。
  9. localsName 如果不使用 with ,localsName 将作为存储局部变量的对象的名称。默认名称是 locals
  10. rmWhitespace 删除所有可安全删除的空白字符,包括开始与结尾处的空格。对于所有标签来说,它提供了一个更安全版本的 -%> (在一行的中间并不会剔除标签后面的换行符)。
  11. escape 为 <%= 结构设置对应的转义(escape)函数。它被用于输出结果以及在生成的客户端函数中通过 .toString() 输出。(默认转义 XML)。
  12. root include使用绝对路径引入时会以此为根路径.
  13. outputFunctionName 指定一个函数名称(例如echoprint)用于在模板语法内打印输出内容.
  14. async 当为true时ejs内部的渲染都将为异步,内部使用(await/async).

测试缓存对于性能的影响,使用的模板和数据如下:

const template = `


<% data.forEach(item=>{ %>
<% if(item.sexCode){ %>

<%= item.name+'的性别是女' %>


<% } else { %>

<%= item.name+'的性别是男' %>


<% } %>
<% }) %>

`;
const data = {
data: [
{
name: '小明',
sexCode: 0
}
,
{
name: '小红',
sexCode: 1
}
]
};

我使用render连续跑1000次使用的时间为480ms.

使用compile进行测试:

const demo = ejs.compile(template);
console.time('start');
let i = 0, len = 1000;
while (i demo(data);
i++;
}
console.timeEnd('start');

最后的结果为15ms,可以看到性能提升是非常明显的.

测试outputFunctionName选项.

const data = {
content:'hello world'
};
const result = ejs.render(`

<% echo(content) %>

`,data,{
outputFunctionName:'echo'
});
console.log(result)

输出:

hello world

测试async选项.

const data = {
content:'hello world'
};
const result = ejs.render(`

<%= content %>

`,data,{
async:true
});
result.then((result)=>{
console.log(result);
})

输出:

hello world

浏览器端使用默认缓存

网上的各种文章中都提到了ejs拥有内部缓存,给render方法提供选项中包含filenamecache属性就可以以filename进行命名然后挂载在ejs内部的缓存对象上.

但是各个文章描述的及其模糊,我查看rendercompile的源码后也没有发现显式使用缓存的选项存在,不过依然找到了一个可以使用缓存后的函数的方法.

// 不要这次的结果,使用缓存
ejs.render(template,data,{
filename: 'test',
cache:true
});
// 获取缓存后的函数
const cacheFun = ejs.cache.get('test');
console.time('start');
let i = 0, len = 1000;
while (i cacheFun(data);
i++;
}
console.timeEnd('start');

最后使用的时间为15ms和使用compile的速度一致.

个人猜测内部缓存功能是为了服务端渲染使用的或者为了配合express使用,没有向浏览器端提供很好的支持.

注意:ejs.clearCache()方法可以清空内部的缓存.

高级操作

包含其他模板

在一般的开发中我们经常将网页切割为多个部分,例如最简单的切割就是将页面分为导航栏`主体区域`页尾三个部分.

在使用的时候经常变化的是主体区域,而页尾不经常变化,但是很多页面需要同样的页尾,这个时候我们就可以将页尾单独拿出来做成一个模板.

ejs中可以使用include命令来插入其他的模板.(注意只能在服务端中操作)

新建两个文件:

header.ejs:


<%= content %>

footer.ejs:


<%= content %>

我们编写以下代码:

const ejs = require('ejs');
const template =
`
<%- include('./header',{content:'我是页头'}) %>


我是内容区域

<%- include('./footer',{content:'我是页脚'}) %>
`;
console.log(ejs.render(template,{
filename:'whatthefuck' // 这个操作中需要一个名称,和路径无关
}));

输出:


我是页头



我是内容区域


我是页脚

有其他需要的朋友可以去查看ejs的github或者中文官网,唯一的额外信息也就这里有了.

参考

https://blog.csdn.net/xjl2713&#8230;

https://www.jianshu.com/p/81e&#8230;

https://blog.csdn.net/zhangxi&#8230;

https://www.cnblogs.com/yedey&#8230;

https://segmentfault.com/a/11&#8230;

https://ejs.bootcss.com/

https://github.com/mde/ejs


推荐阅读
  • 不BB,直接正题一.将大众要领绑定到Page上单个绑定constoldPagePagePagefunction(app){注重大众函数的名字不要反复,不然掩盖app.utilfun ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • express工程中的json调用方法
    本文介绍了在express工程中如何调用json数据,包括建立app.js文件、创建数据接口以及获取全部数据和typeid为1的数据的方法。 ... [详细]
  • OAuth2.0指南
    引言OAuth2.0是一种应用之间彼此访问数据的开源授权协议。比如,一个游戏应用可以访问Facebook的用户数据,或者一个基于地理的应用可以访问Foursquare的用户数据等。 ... [详细]
  • 吐槽:团队遣散,我们该何去何从?
    写在最前:纯属吐槽,漫笔,勿喷!就在前些天,放工回家的路上,看到群信息,说:据说京东裁人了~,也是在上上月,也一度被传的沸沸扬扬的:阿里、京东、华为接踵被曝住手社招,音讯也是满天飘 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文讨论了在使用PHP cURL发送POST请求时,请求体在node.js中没有定义的问题。作者尝试了多种解决方案,但仍然无法解决该问题。同时提供了当前PHP代码示例。 ... [详细]
author-avatar
王责宇0218
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有