JsRender前端渲染模板

使用模板,可以预先自定义一些固定格式的HTML标签,在需要显示数据时,再传入真实数据组装并展示在Web页中;避免了在JS中通过“+”等手动分割、连接字符串的复杂过程;针对高性能和纯字符串渲染进行了优化;无需依赖DOM和jQuery;

优先使用场景:元素重复出现;动态加载数据,并前端显示;

JsRender使用

  1. 引入js
  2. 定义模板
  3. 准备好要显示的数据 json对象
  4. 编译成元素:document.getElementById(“XXX”).render(data); 或 $("#XXX").render(data);
  5. 通过容器元素的append、before、after显示

一、基本语法

  • 原始赋值: {{:属性名}},显示原始数据
  • 转码赋值: {{>属性名}},显示HTML编码后的数据,让数据原样输出
  • 控制语句可嵌套使用:
    • 判断: {{if 表达式}} … {{else}} … {{/if}}
    • 循环: {{for 数组}} … {{/for}}
  • 其它进阶
    • 模板嵌套,使用:{{for tmpl="#另一个模板" /}}
    • 转换器 $.views.converters()定义,使用:{{func:属性名}}
    • 帮助方法 $.views.helpers()定义,使用:{{if ~func(arg1, arg2, ...)}}
    • 自定义标签 $.views.tags()

基本变量标签 {{:name}}

基本变量需要使用冒号 ":" 作为标识,一般是简单对象的某个属性。比如传入一个简单对象data

引入jquery-3.2.1.min.js 和 jsrender.min.js

<script src="/Scripts/jquery-3.2.1.min.js"></script>
<script src="/Content/jsrender.min.js"></script>
<body>
<div id="result"></div> <script type="text/x-jsrender" id="Tmpl">
<p>Name: {{:name}}</p>
<p>Age: {{:age}}</p>
</script> <script>
var data = {
'name': 'van',
'age': 18
} var html2 = $("#Tmpl").render(data);
$("#result").append(html2);
</script>
</body>

传入一个多层级对象data

 <div id="result"></div>

    <script type="text/x-jsrender" id="Tmpl">
<p>Name: {{:Info.name}}</p>
<p>Age: {{:Info.age}}</p>
<p>{{:Details.Address}}</p>
<p>{{:Details.Hobby.TableTennis}}</p>
</script> <script>
var data = {
'Info': {
'name': 'van',
'age': 18
},
'Details': {
'Hobby': {
'TableTennis': 'I like Table Tennis',
'Basketball': 'I like Basketball'
},
'Address': 'My address'
}
} var html2 = $("#Tmpl").render(data);
$("#result").append(html2);
</script>

如上所见,不管传入的对象有多复杂,都能按照层级去找到属性,只是把最外层的对象名 data 省略掉了

启用与定义全局变量的标签{{*}}与 {{*:}}

{{*count = 1}}
<p>{{*:count + 2}}</p> $.views.settings.allowCode(true);

首先需要执行$.views.settings.allowCode(true);,把设置开启,然后使用{{*count = 1}}定义一个变量,然后再用{{*:count}}引用变量。当然,jsrender也提供了只有某一个模板支持全局变量的设置方式

var tmpl = $.templates({
markup: "#myTemplate",
allowCode: true
});

 注释标签 {{!--    --}}

<p>{{!--:Details.Address--}}</p>

条件判断语句 {{if condition}} ... {else condition} ... {{else}}... {{/if}}

jsrender 的 if else 语法跟正常的代码逻辑还是有点区别的,当只有两种情况的时候,是没有区别的,就是 if else

<body>
<div id="result"></div> <script type="text/x-jsrender" id="tmp">
<p>姓名: {{:name}}</p>
<p>
我是:
{{if info.age >= 18}}
成年人
{{else}}
未成年
{{/if}}
</p>
</script>
<script>
var data = {
"name": "van",
info: {
"age": 22
}
};
var html = $("#tmp").render(data);
$("#result").html(html);
</script>
</body>

但是当有多种情况的时候,也就是 if ... else if ... else if ... else 的时候,可是jsrender并没有 else if 这样的写法,它会根据情况来判断,如果是多重情况,它会自动把 else 当做 else if来使用

  <script type="text/x-jsrender" id="tmp">
<p>姓名: {{:name}}</p>
<p>
{{if info.age >= 18}}
大于18岁
{{else info.age >= 16&&info.age < 18}}
大于16岁小于18岁
{{else}}
未成年
{{/if}}
</p>
</script>

if  else 除了以 {{if}}....{{/if}} 的形式使用,也可以使用 {{if xxx=true ... /}} 自闭合的形式,而且还可以引入模板,也可以混着用

    <script type="text/x-jsrender" id="tmp">
<p>姓名: {{:name}}</p>
<p>
{{if info.age >= tmpl="#tmp2" /}}
{{if name=="van"}}
帅~
{{else}}
依旧帅~
{{/if}}
</p>
</script>
<script type="text/x-jsrender" id="tmp2">
<h3>大于18岁</h3>
</script>

使用  {{for}} ... {{/for}} 循环对数据进行循环或对对象进行遍历

jsrender的for循环会默认把数组或对象的第一层循环遍历掉,我们只要管里面的数据就行了,而且使用了循环之后的模板也可以单独写成一个模板,在for循环中引用,循环数组的时候可以使用 {{:#index}} 来获取当前数组的下标,并且index是从0开始的,提醒:尽量使用#getIndex()获取索引,避免使用#index,除非你的应用足够简单。

<div id="result"></div>

    <script type="text/x-jsrender" id="tmp">
{{!-- data 对象已经被默认遍历,所以属性前不用加 data. 就可访问到 --}}
<h3>there have {{:kind}} kinds animal</h3>
<p>and the cow price is {{:price.cow}}</p>
<p>and the cow price is {{:price.pig}}</p> {{!-- 也可以这样对对象进行for循环 --}}
{{for price}}
<p>and the cow price is {{:cow}}</p>
<p>and the cow price is {{:pig}}</p>
{{/for}} <ul>
{{!-- 对对象数组进行循环 --}}
{{for list}}
<li>{{:#getIndex() + 1}}. this animal call {{:name}}, and has {{:count}}, it has {{:foot}} foots</li>
{{/for}}
{{!-- 也可以使用模板引入作为循环的模板 --}}
{{for list tmpl="#tmp2" /}}
</ul> </script>
<script type="text/x-jsrender" id="tmp2">
<li>{{:#getIndex() + 1}}. this animal call {{:name}}, and has {{:count}}, it has {{:foot}} foots</li>
</script> <script>
var data = {
'kind': 4,
'price': {
'cow': 19999,
'pig': 1888
},
'list': [
{
'name': 'cow',
'count': 4,
'foot': 4
},
{
'name': 'chicken',
'count': 5,
'foot': 2
}
]
} var html = $("#tmp").render(data);
$("#result").html(html);
</script>

嵌套for

 <div id="result"></div>

    <script type="text/x-jsrender" id="tmp">
{{for}}
<li>
Name:{{:name}}
<ul>
{{for hobbies}}
<li>{{:#getIndex() + 1}}-{{:#data}}</li>
{{/for}}
</ul>
</li>
{{/for}}
</script> <script>
var data = [
{ name: "tom", hobbies: ["篮球", "足球"] },
{ name: "jack", hobbies: ["篮球", "橄榄球"] },
{ name: "lucy", hobbies: ["游泳", "羽毛球"] }
];
var html = $("#tmp").render(data);
$("#result").html(html);
</script>

嵌套循环使用参数访问父级数据

 <table border="1">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>家庭成员</th>
</tr>
</thead>
<tbody id="result"></tbody>
</table> <script type="text/x-jsrender" id="tmp">
{{for}}
<tr>
<td>
{{:#getIndex() + 1}}
</td>
<td>{{:name}}</td>
<td>{{:age}}</td>
<td>
{{!-- 使用for循环时,可以在后边添加参数,参数必须以~开头,多个参数用空格分隔 --}}
{{!-- 通过参数,我们缓存了父级的数据,在子循环中访问参数,就可以间接访问父级数据 --}}
{{for family ~parentIndex=#getIndex() ~parentName=name ~parnetAge=age}}
<b>{{:~parentIndex + 1}}.{{:#getIndex() + 1}}</b>
{{!-- #data相当于this --}}
{{:~parentName}}的{{:#data}}
{{/for}}
</td>
</tr>
{{/for}}
</script>
<script>
var data = [
{
name: "张三",
age: 3,
family: ["爸爸", "妈妈", "哥哥"]
},
{
name: "李四",
age: 4,
family: ["爷爷", "奶奶", "叔叔"]
}
];
var html = $("#tmp").render(data);
$("#result").html(html);
</script>

当循环数组或者遍历对象的时候,如果在 {{for}} {{/for}} 中间加上 {{else}},还可以对遍历的对象进行判断,如果该对象或者属性不存在,那么就显示其他的内容。

{{!-- 遍历的时候顺便判断merbers是否存在 --}}
{{for members}}
<div>{{:name}}</div>
{{else}}
<div>No members!</div>
{{/for}}

 使用 {{props}} 遍历对象并且获取到对象的key/value

当我们遍历对象需要使用到对象的key值时,使用props可以获取到key/value值,而且也可以在for循环中进行对象的遍历,在数据循环中获取可以使用#data获取到当前的对象,当然也可以使用引入外部模板来当做循环模板。

    <div id="result"></div>

    <script type="text/x-jsrender" id="tmp">
{{!-- 简单的对象遍历 --}}
{{props price}}
<p>the {{:key}} price is {{:prop}}</p>
{{/props}}
<ul>
{{!-- 在数据循环中再进行对象的遍历,病获取到key/prop --}}
{{for list}}
<li>
{{:#index + 1}}.
{{props #data}}
<b>{{:key}}</b> is {{>prop}}
{{/props}}
</li>
{{/for}} {{!-- 也可以使用模板引入作为循环的模板 --}}
{{for list tmpl="#tmp2" /}} </ul>
</script>
<script type="text/x-jsrender" id="tmp2">
<li>
{{:#index + 1}}.
{{props #data}}
<b>{{:key}}</b> is {{>prop}}
{{/props}}
</li>
</script> <script>
var data = {
'kind': 4,
'price': {
'cow': 19999,
'pig': 1888
},
'list': [
{
'name': 'cow',
'count': 4,
'foot': 4
},
{
'name': 'chicken',
'count': 5,
'foot': 2
}
]
} var html = $("#tmp").render(data);
$("#result").html(html);
</script>

当然,也可以在prop遍历对象的时候对对象进行判断,只要在prop遍历中加入 {{else}},如果对象为undefined或对象为空,那么就执行else

{{props address}}
<b>{{:key}}:</b>{{:prop}} <br />
{{else}}
The address is blank (no properties)!
{{/props}}

使用 {{include}} 引入外部模板或者改变模板的上下文

虽然我们可以在 {{for}} 循环中或者 {{if}} 标签中直接引入模板,但是 {{include}} 引入模板才是符合我们认知的,应该什么标签干什么事

 <script type="text/x-jsrender" id="tmp">
{{if case == 1}}
{{include tmpl="#tmp1" /}}
{{else case == 2}}
{{include tmpl="#tmp2" /}}
{{else}}
<p>no data</p>
{{/if}}
</script>

使用{{include}}标签引入模板显得比较语义化,虽然并没有什么差别。除了引入模板,{{include}}还可以在引入模板的同时引入对象或者数组,来改变所引入模板的上下文

 <div id="result"></div>

    <script type="text/x-jsrender" id="tmp">
{{if case == 1}}
{{include data tmpl="#tmp1" /}}
{{else case == 2}}
{{include data1 tmpl="#tmp2" /}}
{{else}}
<p>no data</p>
{{/if}}
</script>
<script type="text/x-jsrender" id="tmp1">
{{!-- for循环会默认取到传进来的对象 使用data.title是访问不到的 --}}
{{!-- 传进来的对象必须手动循环 --}}
{{for}}
<h3>{{:title}}</h3>
<p>{{:text}}</p>
{{/for}}
</script>
<script type="text/x-jsrender" id="tmp2">
{{!-- :length 可以获取当前数组的长度 --}}
{{:length}}
{{!-- 传进来的数组必须手动循环 --}}
{{for #data}}
<h3>{{:title}}</h3>
<p>{{:text}}</p>
{{/for}}
</script> <script>
var condition = {
'case': 2,
'data': {
'title': 'this is first case',
'text': 'case one text'
},
'data1': [
{
'title': 'i am outer fisrt title',
'text': 'it is me,diffrent light'
},
{
'title': 'i am outer second title',
'text': 'it is me,diffrent light'
}
]
}; var html = $("#tmp").render(condition);
$("#result").html(html);
</script>

使用 {{converters:value}} 把value转换成所需要的格式

当后端给我们返回的数据格式跟页面所展示的格式不一样的时候,我们就需要对数据进行转换。比如说后端返回时间的毫秒数,可是页面却要显示 年-月-日 的格式或者是后端返回小写的字符,页面却要显示成大写的字符,这个时候转换器就派上用场了。
jsrender提供了api $.views.converters()来注册转换方法。
    <div id="result"></div>

    <script type="text/x-jsrender" id="tmp">
<div>
<h3>{{upper:name}}</h3>
<p>{{:age}}</p>
</div>
</script> <script>
var condition = {
'name': 'van',
'age': 20
}; $.views.converters({
upper: function (val) {
return val.toUpperCase();//转大写
}
}) var html = $("#tmp").render(condition);
$("#result").html(html);
</script>

使用 {{:~helper(value)}} 对传入的参数value做处理

当我们拿到的数据不符合展示的需求是,我们需要对数据进行处理,那么我们可以使用辅助函数,把原始值当成参数传入,返回我们需要的数据。
jsrender提供了$.views.helper()方法来注册辅助函数。并使用~当前缀来调用辅助函数。

 <div id="result"></div>

    <script type="text/x-jsrender" id="tmp">
<div>
<h3>{{:~hello(firstName, lastName)}}</h3>
<p>{{:age}}</p>
</div>
</script> <script>
var info = {
firstName: 'van',
lastName: 'wu',
age: 18
}; $.views.helpers({
hello: function (fisrtName, lastName) {
return 'Hello ' + fisrtName + ' ' + lastName;
}
}) var html = $("#tmp").render(info);
$("#result").html(html);
</script>

以上就是JsRender的基本用法,下篇会学习JsRender的一些常用API。

参考:https://www.cnblogs.com/duanyue/p/6899103.html

https://www.cnblogs.com/Leo_wl/p/5898142.html

https://www.jianshu.com/p/3151d2256410

JsRender 前端渲染模板基础学习的更多相关文章

  1. 云平台项目--学习经验--jsrender前端渲染模板

    jsrender的好处:可以预先自定义一些固定的html标签,在需要显示数据的时候,可以直接传入真实的数据并显示在web页面中,避免了Js编写中的复杂过程:针对高性能和纯字符串渲染并优化,不需要依赖D ...

  2. JsRender 前端渲染模板常用API学习

    JsRender 常用API 1. $.templates() $.templates()方法是用来注册或编译模板的,使用的情况有以下几种. 把html字符串编译编译成模板 获取使用script标签声 ...

  3. 前端渲染模板(一):Thymeleaf

    一.使用 本篇文章将以SpringBoot为框架来介绍Thymeleaf的用法. 1 资源文件的约定目录结构  Maven的资源文件目录:/src/java/resources spring-boot ...

  4. web前端——Vue.js基础学习

    近期项目的前端页面准备引入Vue.js,看了网上一些简介,及它和JQuery的对比,发现对于新入门的前端开发来说,Vue 其实也是比较适用的一个框架,其实用性不比JQuery差,感觉还挺有意思,于是研 ...

  5. Django框架之前端渲染-模板层

      Django 模板层   Django 模板层 前后端数据传递 (1) 后端朝前端页面传递数据的方式: # 将当前所在的名称空间中的名字全部传递给前端页面 # 第一种 return render( ...

  6. web前端——Vue.js基础学习之class与样式绑定

    打着巩固 css 知识的旗号开始了对 vue 样式绑定的研究,相比前一篇的 demo,本次内容多了各种样式在里面,变得稍微花哨了些,话不多说,直接上代码吧: <html> <head ...

  7. 前端渲染利器——JsRender入门

    JsRender不少前端人员应该都用过,它是一个比较强大的模板,不牵涉太多技术依赖,使用起来非常舒服.我本人在前端开发中使用React之前,都是用的它了(实际上我感觉React没有JsViewes好用 ...

  8. [Vue 牛刀小试]:第十七章 - 优化 Vue CLI 3 构建的前端项目模板(1)- 基础项目模板介绍

    一.前言 在上一章中,我们开始通过 Vue CLI 去搭建属于自己的前端 Vue 项目模板,就像我们 .NET 程序员在使用 asp.net core 时一样,我们更多的会在框架基础上按照自己的开发习 ...

  9. HTML5零基础学习Web前端需要知道哪些?

    HTML零基础学习Web前端网页制作,首先是要掌握一些常用标签的使用和他们的各个属性,常用的标签我总结了一下有以下这些: html:页面的根元素. head:页面的头部标签,是所有头部元素的容器. b ...

随机推荐

  1. spring注解第02课 包扫描@ComponentScan、@ComponentScans

    1.配置文件形式: <context:component-scan base-package="com.atguigu" /> spring会扫描此包下的@Servic ...

  2. Prolog 逻辑推导语言

    Prolog https://en.wikipedia.org/wiki/Prolog Prolog is a general-purpose logic programming language a ...

  3. mssql 创建函数简单实例

    CREATE FUNCTION [dbo].[f_DailyIncome] ( @userId int, @date date ) ,) AS BEGIN ,); ) from Channel_Use ...

  4. luogu P3338 [ZJOI2014]力

    传送门 首先化简原式\[F_j=\sum_{i<j}\frac{q_iq_j}{(i-j)^2}-\sum_{i>j}\frac{q_iq_j}{(i-j)^2},E_j=F_j/q_j\ ...

  5. nnet3中的数据类型

    目标与背景 之前的nnet1和nnet2基于Component对象,是一个组件的堆栈.每个组件对应一个神经网络层,为简便起见,将一个仿射变换后接一个非线性表示为一层网络,因此每层网络有两个组件.这些旧 ...

  6. javascript删除cookie

    代码很简单 function deleteCookie (cookieName) { document.cookie = `${cookieName}=; expires=${new Date(0). ...

  7. Luogu P3700「CQOI2017」小Q的表格

    为什么我连分块都想不到啊... 题意 定义一个矩阵$f$满足 $ f(a,b)=f(b,a)$ $ b·f(a,a+b)=(a+b)·f(a,b)$ 初始$ f(a,b)=ab$ 有$ m$次修改,每 ...

  8. 编写blog第一天

    今天玩的比较嗨,离开学还剩半个月了,之前在网上搜集了一些blog制作方面的资料,并且在博客园注册了一个账号,今天才打开了申请已久的blog,现在已经对blog具有的基本功能和界面布局有了比较全面的掌握 ...

  9. Codeforces Round #545 (Div. 2)(B. Circus)

    题目链接:http://codeforces.com/contest/1138/problem/B 题目大意:贼绕口的题目,就是给你两个字符串s1,s2,然后每一个人代表一列,第一列代表技能一每个人是 ...

  10. Java对象的浅拷贝和深拷贝&&String类型的赋值

    Java中的数据类型分为基本数据类型和引用数据类型.对于这两种数据类型,在进行赋值操作.方法传参或返回值时,会有值传递和引用(地址)传递的差别. 浅拷贝(Shallow Copy): ①对于数据类型是 ...