模板引擎mustache学习之多层嵌套tokens变html文本(最终篇)

126 阅读2分钟

现在的文件目录如下:

1.png

新增: 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;
  },
};

最终效果输出如下:

(@P7}18BBNRF%ZG825_E2.png

结语: 至止我们简化版的mustache模板引擎就手写完成!NICE 从中学到不少! 如

  1. 一维变多维 嵌套数组!
  2. 递归tokens变成html文本
  3. 有时会碰到 obj['a.b.c'] 需求使用lookup函数方式就能解决!