mustache模板引擎

mustache库的机理

image.png
  1. 将模板字符串编译为tokens形式
  2. 将tokens结合数据,解析为dom字符串

一、tokens

tokens是js的嵌套数组:


image.png

当模板字符串中有循环存在时,它将被编译成嵌套更深的tokens。

二、模板字符串解析tokens的过程

    1. 定义一个Scanner类,类中包含两个方法:scan和scanUntil


      image.png

      scan:路过指定内容,没有返回值
      scanUntil:让指针进行扫描,知道遇见指定内容结束,并返回结束之前路过的文字

class Scanner{
  constructor(templateStr){
    this.templateStr = templateStr
    this.pos = 0 // 指针
    this.tail = templateStr // 指针尾,刚开始时指向原字符串
  }
  scan(tag){
    if(this.tail.indexOf(tag)===0){
      // tag有多少位就让tail后移多少位
      this.pos += tag.length
      this.tail = this.templateStr.substring(this.pos)
    }
  }
  scanUntil(stopTag){
    // 记录执行本方法时pos的值
    let pos_up = this.pos
    // 当指针尾不等于要跳过的目标字符串时,指针一直向后移动
    while(this.tail.indexOf(stopTag)!==0 && this.pos
    1. 将解析出来的字符串变成tokens
      渲染方法render()让模板字符串变成tokens数组(如下图);


      image.png

      折叠tokens,将#和/之间的数组整合起来作为子数组(利用collector收集器变量):

function parseTokens(tokens){ 
  let res = [] // 存储最终返回结果
  let sections = [] // 一个栈结构,来表示是否有嵌套数组
  let collector = res // 收集器,用来收集嵌套数组,指向结果数组,因为数组是引用类型,所以collector和res指向同一个数组
  for(let i=0; i0?sections[sections.length-1][2]:res
        break;
      default:
        collector.push(token) // 将每一项token存入collector数组
    }
  }
return res;
}
    1. 将tokens结合数据,解析为dom字符串
      其中有一个问题是,js不能将带有点符号的数据(如 {{item.label}} )解析出来,所以需要编写lookup函数:
// lookup函数从一个对象中读取出嵌套的值,如下lookup(dataObj, 'a.b.c')值为123
let dataObj = {
  a: {
    b: {
      c: 123
    }
  }
}
function lookup(dataObj, keyName){
  // 如果keyName里面有点符号
  if(keyName.indexOf('.')!==-1){
    let keys = keyName.split('.')
    let temp = dataObj
    for(let i=0; i

最后判断token[0]的值,若是"text"则与结果字符串直接拼接,若是"name"则取data中对应的值之后再拼接,若是"#"说明有嵌套数组则要递归。

你可能感兴趣的:(mustache模板引擎)