前言
这是我参与「第四届青训营 」笔记创作活动的第3天
随着挨踢行业的不断内卷化,了解Vue框架的底层原理已刻不容缓。
数据变为视图的方法
问题:如果我们要将下面的arr循环渲染成无序列表,该怎么做呢?
var arr = [
{ "name": "小明", "age": 12, "sex": "男" },
{ "name": "小红", "age": 11, "sex": "女" },
{ "name": "小强", "age": 13, "sex": "男" }
];
解决方案:
- 纯DOM:非常笨拙,没有实战价值,最为底层
- 数组join法:曾几何时非常流行,是曾经前端必会的知识
- ES6的反引号法:ES6中新增的
${a}语法糖,好用
- 模板引擎:可省略循环语句,解决数据变为视图最优雅的方法
今天就模板引擎着重讲一下------
mustache库
简介
- mustache官方git: github.com/janl/mustac…
- mustache是“胡子”的意思,因为它的嵌入标记{{ }}非常像胡子
- 没错,{{ }}的语法也被Vue沿用,这就是我们学习mustache的原因
- mustache是最早的模板引擎库,比Vue诞生的早多了,它的底层实现机理在当 时是非常有创造性的、轰动性的,为后续模板引擎的发展提供了崭新的思路
基本使用
了解
- 必须要引入mustache库,可以在bootcdn.cn上找到它
- mustache的模板语法非常简单,比如前述案例的模板语法如下:
<ul>
// 循环开始
{{#arr}}
<li>
<div class="hd">{{name}}的基本信息</div>
<div class="bd">
<p>姓名:{{name}}</p>
<p>性别:{{sex}}</p>
<p>年龄:{{age}}</p>
</div>
</li>
{{/arr}}
// 循环结束
</ul>
循环对象数组
- 引入mustache.js第三方库,就会提供一个
Mustache的全局对象 Mustache.render(templateStr, data)
注:templateStr 是 要填的模板字符串,data 是要循环渲染的数据。
下面代码执行就可以生成无序列表了!!!
<div id="container"></div>
<!-- 模板 -->
<script type="text/template" id="mytemplate">
<ul>
{{#arr}}
<li>
<div class="hd">{{name}}的基本信息</div>
<div class="bd">
<p>姓名:{{name}}</p>
<p>性别:{{sex}}</p>
<p>年龄:{{age}}</p>
</div>
</li>
{{/arr}}
</ul>
</script>
// 引入mustache库
<script src="jslib/mustache.js"></script>
<script>
var templateStr = document.getElementById('mytemplate').innerHTML;
var data = {
arr: [
{ "name": "小明", "age": 12, "sex": "男" },
{ "name": "小红", "age": 11, "sex": "女" },
{ "name": "小强", "age": 13, "sex": "男" }
]
};
var domStr = Mustache.render(templateStr, data);
var container = document.getElementById('container');
container.innerHTML = domStr;
</script>
数组的嵌套
<div id="container"></div>
<script src="jslib/mustache.js"></script>
<script>
var templateStr = `
<ul>
{{#arr}}
<li>
{{name}}的爱好是:
<ol>
{{#hobbies}}
<li>{{.}}</li>
{{/hobbies}}
</ol>
</li>
{{/arr}}
</ul>
`;
// {{#hobbies}}...{{/hobbies}}表示循环数组arr中的各数组hobbies
var data = {
// 数组嵌套
arr: [
{'name': '小明', 'age': 12, 'hobbies': ['游泳', '羽毛球']},
{'name': '小红', 'age': 11, 'hobbies': ['编程', '写作文', '看报纸']},
{'name': '小强', 'age': 13, 'hobbies': ['打台球']},
]
};
var domStr = Mustache.render(templateStr, data);
var container = document.getElementById('container');
container.innerHTML = domStr;
</script>
正则表达式实现模板数据填充
- 在较为简单的情况下,可以用正则表达式实现
var templateStr = '<h1>我买了一个{{thing}},花了{{money}}元,好{{mood}}</h1>';
var data = {
thing: '白菜',
money: 5,
mood: '激动'
};
// 最简单的模板引擎的实现机理,利用的是正则表达式中的replace()方法。
// replace()的第二个参数可以是一个函数,这个函数提供捕获的东西的参数,就是$1
// 结合data对象,即可进行智能的替换
function render(templateStr, data) {
return templateStr.replace(/\{\{(\w+)\}\}/g, function (findStr, $1) {
return data[$1];
});
}
var result = render(templateStr, data);
console.log(result);
- 但是当情况复杂时,正则表达式的思路肯定就不行了。比如这样的模板字符串, 是不能用正则表达式的思路实现的
mustache库的机理
mustache库的机理大致可归纳为:
- 将模板字符串编译为tokens形式
- 将tokens结合数据,解析为dom字符串
底层tokens思想
1.先了解一下什么是tokens:
- tokens是一个JS的嵌套数组,说白了,就是模板字符串的JS表示
- 它是“抽象语法树”、“虚拟节点”等等的开山鼻祖
2.将模板字符串编译为tokens:
3.至于如何将模板字符串编译为tokens,看下行代码
// 引入mustache库
<script src="jslib/mustache.js"></script>
<script>
var templateStr2 = `
<ul>
{{#arr}}
<li>
{{name}}的爱好是:
<ol>
{{#hobbies}}
<li>{{.}}</li>
{{/hobbies}}
</ol>
</li>
{{/arr}}
</ul>
`;
// 将模板字符串编译为`tokens`
Mustache.render(templateStr2, {});
</script>
执行上述代码,效果如下:
总结
学习源码时,源码思想要借鉴,而不要抄袭。记得多敲多想,你会有不一样的收获哦。源码参悟之时,年薪百万之日!