JsRender前端渲染模板
使用模板,可以預先自定義一些固定格式的HTML標籤,在需要顯示數據時,再傳入真實數據組裝並展示在Web頁中;避免了在JS中通過“+”等手動分割、連接字符串的複雜過程;針對高性能和純字符串渲染進行了優化;無需依賴DOM和jQuery;
優先使用場景:元素重複出現;動態加載數據,並前端顯示;
JsRender使用
- 引入js
- 定義模板
- 準備好要顯示的數據 json對象
- 編譯成元素:document.getElementById(“XXX”).render(data); 或 $("#XXX").render(data);
- 通過容器元素的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 >= 18 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>