在這個重複造輪子的時代,新的技術每時每刻可能都在誕生。起初是想做一個建構工具,結果寫了一個簡單的内容管理系統(PrvtCMS),目前使用mustache.js作服務端渲染。
本着物盡其用的原則,我們不僅要使用,還要創造更深入的用法。現在讓我們一起進入程式設計世界吧。
github位址:https://github.com/janl/mustache.js
基本文法
名稱 | 使用方法 |
變量 | {{content}} |
帶有HTML的變量 | {{{content}}} |
循環 | {{#navs}} ...... {{/navs}} {{#keys}} {{.}} {{/keys}} 數組循環的時候可以用 . 作為下标 |
if else | {{#loginStatus}} ...... {{/loginStatus}} {{^loginStatus}} ...... {{/loginStatus}} |
布爾判斷 | 和前面循環的文法是一樣的,取決于變量是否是一個數組 {{#data}} ...... {{/data}} |
數組的布爾判斷 | {{#datas.length}} ...... {{/datas.length}} |
Lambdas | 遇到和前面的循環和布爾表達式一樣,取決于參數的類型 {{#person}} {{name}} is awesome. {{/person}} |
兩個核心方法 | Mustache.parse(template); Mustache.render(template, obj); |
基本用法
<script src="/libs/mustache.js/4.1.0/mustache.min.js"></script>
<script type="text/javascript">
const obj = {title: '熱門推薦'};
const template = '您目前正在通路:{{title}}。';
const res = Mustache.render(template, obj);
console.log(res);
// 您目前正在通路:熱門推薦。
</script>
循環的使用
<script type="text/javascript">
const navs = [
{ id: '1', title: '首頁' },
{ id: '2', title: '産品管理', child: [
{ id: '3', title: '辦公裝置' }
]}
];
const obj = { navs: navs };
const template = `
<ul>
{{#navs}}
<li>
<a href="/list?navid={{id}}">{{title}}</a>
{{#child.length}}
<ul>
{{#child}}
<li>
<a href="/list?navid={{id}}">{{title}}</a>
</li>
{{/child}}
</ul>
{{/child.length}}
</li>
{{/navs}}
</ul>
`;
const res = Mustache.render(template, obj);
console.log(res);
/**
<ul>
<li>
<a href="/list?navid=1">首頁</a>
</li>
<li>
<a href="/list?navid=2">産品管理</a>
<ul>
<li>
<a href="/list?navid=3">辦公裝置</a>
</li>
</ul>
</li>
</ul>
*/
</script>
Lambdas自定義函數
官方執行個體
<script type="text/javascript">
const obj = {
"name": "Willy",
"person": function() {
return function(text, render) {
return "<b>" + render(text) + "</b>"
}
}
};
const template = `{{#person}} {{name}} is awesome. {{/person}}`;
const res = Mustache.render(template, obj);
console.log(res);
//<b> Willy is awesome. </b>
</script>
假設我們現在有一個需求,不顯示個人中心導航。
這是PrvtCMS内部的功能實作,如果您有更好的方式,歡迎交流。
<script type="text/javascript">
const obj = {
navs: [
{ id: '1', title: '首頁' },
{ id: '9', title: '個人中心' }
],
arrayFunctions: function() {
return function(text, render) {
const options = this;
const conditions = text.match(/(?<={{#)\w+=>[^}]+(?=}})/gi) || [];
if(!conditions || !conditions .length) return render(text);
const key = conditions[0];
const fns = key.match(/(?<=\=\>)[a-z]+[\(][^\)]+[\)]/gi) || [];
let datas = [];
fns.map(fn => {
const attrKey = (key.match(/^\w+/) || [''])[0];
const dataCds = fn.match(/(?<=[\s\(])\w+([=]+(["']).*?(?<=[^\\])\2)*/g);
if (attrKey) {
if (/^filter/.test(fn)) {
const filtercdn = fn.replace(/^\w+\(/, '').replace(/\)$/, '');
const filters = filtercdn.match(/^([\(\!&\|]*\w+[!=<>]+((["']).*?(?<=[^\\])\3|true|false|\d+)[\)]*)+$/);
if (filters && filters.length) {
if (((options)[attrKey])) {
datas = ((options)[attrKey]).filter((data) => {
return eval(filtercdn.replace(/((?<=[\(&\|])|^)\w+/g, (str) => 'data.' + str));
})
}
}
}
}
});
(options)[key] = datas;
return render(text);
}
}
};
const template = `
<ul>
{{#arrayFunctions}}{{#navs=>filter(title!='個人中心')}}
<li><a href="/list?navid={{id}}">{{title}}</a></li>
{{/navs=>filter(title!='個人中心')}}
{{/arrayFunctions}}
</ul>
`;
const res = Mustache.render(template, obj);
console.log(res);
/**
<ul>
<li><a href="/list?navid=1">首頁</a></li>
</ul>
*/
</script>
服務端與前端共用元件
PrvtCMS目前服務端與前端共用元件采用的方式。
服務端:{%title%}
用戶端:{{data.title}}
// 服務端先處理
const navs = [
{ id: '1', title: '首頁', type:1 },
{ id: '2', title: '産品管理', type: 3}
];
const options = { navs: navs };
const template = `
<ul>
{%#navs%}
<li :class="getNavClass({%type%})">
<a href="/list?navid={%id%}">{%title%}</a>
</li>
{%/navs%}
</ul>
`;
Mustache.render(template, options, {}, ['{%', '%}']);
//前端處理
{
// data ...
getNavClass(type){
// ...
}
// ...
}
線上演練
網址:https://www.prvt.site/mustache.js
人人為我,我為人人,一起加油吧。