现在的文件目录如下:
新增: lookup.js renderDom.js parseArray.js
lookup.js
/***
* 作用: 对于有些对象有深层嵌套的如 a: {b: { c: 666 }}; 如果我们想通过c的值666 这样格式的a['b.c'] JS是不能读取的哦
*
*/
export default function (obj, key) {
if (key.indexOf(".") !== -1 && key != ".") {
// 如果有.我们就要进行切割成数组
const keys = key.split(".");
let tempObj = obj; // 临时存放到一个变量
for (let i = 0, len = keys.length; i < len; i++) {
tempObj = tempObj[keys[i]]; // 这里是关键哈 第一次是a.b 下一次就变成 a.b.c 最终就能取出值了!
}
return tempObj;
}
return obj[key];
}
renderDom.js
/**
* 作用:将多层嵌套数组转换成dom字符串 注:是dom字符串 变不是dom!!!
*
*/
import lookup from "./lookup";
import parseArray from "./parseArray";
export default function (tokens, data) {
let result = "";
// 循环遍历tokens 多维数组
for (let i = 0, len = tokens.length; i < len; i++) {
let token = tokens[i];
if (token[0] === "text") {
// 这种好处理直接拼接上去就好了
result += token[1];
} else if (token[0] === "name") {
// 如果是name类型,那么就直接使用它的值,当然要用lookup
// 因为防止这里是“a.b.c”有逗号的形式 在vue中我们是不是写过如: item.name
result += lookup(data, token[1]);
} else if (token[0] === "#") {
// 这里由于是多层数组嵌套所以要用到递归
result += parseArray(data, token);
}
}
return result;
}
parseArray.js
import lookup from "./lookup";
import renderDom from "./renderDom";
/**
*
* @param {*} data 数组
* @param {*} token 每一项token 单个token哦
*/
export default function (data, token) {
let result = "";
// 这里一样还需要lookup一下取出 token[1]: 代表数组的key
let currentToken = lookup(data, token[1]); // token[1] 因为第0项是 标识如text name # /等
for (let i = 0, len = currentToken.length; i < len; i++) {
// 这里需要考虑有. 或者里面要是一个数组的情况
result += renderDom(token[2], { ...currentToken[i], ".": currentToken[i] }); // 这里就形成了递归调用
}
return result;
}
index.js
import parseTemplateToTokens from "./parseTemplateToTokens";
import renderDom from "./renderDom";
window.Mustache = {
render(tempStr, data) {
// 1. 将模板字符串转成tokens
const tokens = parseTemplateToTokens(tempStr);
// 2. 将多层嵌套数组转成html字符串
const html = renderDom(tokens, data);
console.log(html);
// 3. 最终返回html文本 再在index.html中进行挂载一下
return html;
},
};
最终效果输出如下:
结语: 至止我们简化版的mustache模板引擎就手写完成!NICE 从中学到不少! 如
- 一维变多维 嵌套数组!
- 递归tokens变成html文本
- 有时会碰到 obj['a.b.c'] 需求使用lookup函数方式就能解决!