一、mustache 了解
- 关于mustache:mustache主页
- GitHub:git 地址
二、手写mustache核心
2.1、得到 tokens
-
全局变量
//templateStr:模板字符串 var templateStr = ` <ul> 介绍: {{#list}} <li>爱好: {{#hobb}} <li>{{age}}</li> {{/item.hobb}} </li> {{/list}} </ul>`; var pos = 0; var tail = templateStr; //剩余的字符串 var tokens = []; //模板预编译形成的一维数组tokens var nestTokens = []; //对一维数组 进行整理(嵌套) var sections = []; //整理过程中采用 栈 思想
-
主函数代码
while (pos < templateStr.length) { let word = sanUtil("{{"); tokens.push(['text', word]); san("{{"); // 过滤掉 {{ 符号 word = sanUtil("}}"); if (word[0] == '#' || word[0] == '/') { tokens.push([word[0], word.substring(1)]); } else if (word != "") { tokens.push(['name', word]); } san("}}"); }
-
sanUtil( ) 函数
function sanUtil(stopTag) { // debugger let begin_pos = pos; while (tail.indexOf(stopTag) != 0 && pos < templateStr.length) { pos++; tail = templateStr.substring(pos);//更新剩余字符串 } return templateStr.substring(begin_pos, pos); // 返回 {{ 符号左边的字符串 }
-
san( ) 函数
function san(tag) { if (tail.indexOf(tag) == 0 && pos < templateStr.length) { tail = tail.substring(tag.length); pos += tag.length; } }
-
此时得到tokens:
2.2、得到 nestTokens,栈
function nestToken(tokens){
// debugger ;
for(let i = 0;i<tokens.length;i++){
let token = tokens[i];
switch(token[0]){
case '#':
// 收集子元素 token[1]
token[2] = [];
//进栈
sections.push(token);
break;
case '/':
// 出栈 section 接收出栈的数据
let section_pop = sections.pop();
if(sections.length==0){
nestTokens.push(section_pop);
}else{
sections[sections.length-1][2].push(section_pop);
}
break;
default:
if(sections.length == 0){
nestTokens.push(token)
}else{
sections[sections.length-1][2].push(token);
}
}
}
}
此时nestTokens:
[
['text','<ul>介绍:'],
['#',list,
['text','<li>爱好:'],
['#','item.hobb',
['text','<li>'],['name','age'],['text':'</li>']
]
['text','</li>'],
],
['text','</ul>']
]