跟着B站学前端之第一课:VUE2源码解析之mustache模板引擎

手写响应式数据系统底层、手写模板编译系统底层、手写虚拟DOM和diff算法底层……拒绝纸上谈兵,手撸一个自己的Vue框架!

源码重点:模板技术、数据劫持、虚拟节点、最小量更新、抽象语法树等等

Vue源码解析之mustache模板引擎

1.什么是模板引擎
2.mustache基本使用
3.mustache的底层核心机制
4.手写一个mustache库
5.总结

1.什么是模板引擎

历史上曾经出现的数据转为视图的方案
  • 纯DOM法:原生JS创建DOM节点,以及样式、类名、DOM结构关系,然后append到页面上(document.createElement('ul').appendChild('li').className().style.setProperty)
  • 数组jion法:遍历数组,然后用字符串jion方法添加到innerHtml里
  • ES6模板字符串,支持换行, ${var}支持变量
  • 模板引擎:mustache.js 是一个简单强大的 JavaScript 模板引擎,使用它可以简化在 js 代码中的 html 编写。

2.mustache基本使用

mustache是最早的模板引擎,vue只是引用了语法,引入mustache库才能使用
1.cdn引入(https://cdn.bootcdn.net/ajax/libs/mustache.js/4.2.0/mustache.js)
2.模板、数据、绑定、渲染四个步骤

// 模板 {{#arr}} {{age}}{{.}}{{/arr}}
var templateStr = document.getElementById('my-tem').innerHTML          
// 数据
const data = {
    arr: [],
}           
// 绑定
var domStr  = mustache.render(templateStr, data)
// 渲染
document.getElementById('app').innerHTML= domStr

3.mustache的底层核心机制

渲染过程

4.手写一个mustache库

具体实现的步骤:

  1. Scanner类:储存templateStr,pos,tail,实现过指定字符串并返回内容的函数
  2. 生成tokens:生成scan实例,遍历模板字符串,使用scan{{拿到text的内容并存进tokens中;使用}}拿到要渲染的内容进行分类:如果是#开头说明要循环,存入#类型的数组,值为数组的key;如果是/开头存入/类型,值为数组;其他情况则是data的key,存入name类型
  3. tokens数组的折叠:维护一个栈sections和数组指针current,添加内容都在栈顶添加(栈中如果没有元素则代表是根数组tokens数组),遇到token项类型为'#',则压栈(包括sections和当前数组),开辟第三个位置数组,并将current指向栈顶元素,遇到token项类型为'/',则直接出栈,并考虑current是否指向根数组;其他情况则为name或者text的token直接存至current数组中去。
  4. tokens和data结合生成HTML:对tokens数组进行每一项类型检查:如果为text,直接加进htmlStr中去;如果为name,将数据值加入htmlStr;如果为#,则需要进行递归调用,将这一项的子tokens和封装了.属性的子对象传入参数。
  5. 最后返回整个htmlStr,传入模板字符串与数据,在html文件中进行调用
    var domstr = MY_templateEngine.render(str, data)
    document.getElementById('app').innerHTML=(domstr)
export default function render(templateStr,Data){
    //生成tokens
    let tokens = genTokens(templateStr);
    //生成HTML
    let htmlStr = renderTemplate(tokens,Data);
    return htmlStr;
}
function genTokens(templateStr){
    //生成初始tokens
    let initTokens = initTokens(templateStr);
    //生成折叠后的tokens
    let resultTokens = nestTokens(initTokens);
    return resultTokens;
}
function initTokens(templateStr){
    let initTokens = [];
    let pos = 0;
    return initTokens;
}
function nestTokens(initTokens){
    let resultTokens = [];
    return resultTokens;
}
function renderTemplate(tokens,Data){
    let htmlStr = '';
    return htmlStr;
}

5.总结:

未涉及到vue的模板指令v-for,v-if等等,但它们都是基于mustache,都是将数据转成视图。

Mustache底层太美了!tokens的意义也不言自明了。如果没有token,那么数组的循环形式,就很难处理。我们通过本课,确实学到了很多,视野面变得更广,感觉肚子里的东西更多了;

在Mustache源码中,还有Context类和Writer类,在我们的代码演示中, 都将它们进行了简化,但是不影响主干功能的实现。我们的这个“简化版本的”代码非常值得大家进行手写,你会受益良多的!当然,如果有精力,可以再研究透彻这个“简化版本的”代码后,自己对Mustache原包进行学习;

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容