mustache是最早的模板引擎 比vue的诞生还要早很多 而他的语法 就是基于 {{ }} 这样的双花括号
mustache属于通用性的应用 他既可以在浏览器中直接用 也可以在npm中使用
这里 我们为了方便 就直接去拿在浏览器中使用的包了 没必要再自己搭个环境
大家可以下载我上传的资源
vue源码探究辅助工具mustache.js
我们随便找一个目录 创建一个html文件和一个文件夹叫js
然后将刚刚弄来的mustache.js放进js文件夹中
然后 我们打开 mustache.js
他的最后一段代码是一个导出的语法
我们html环境显然不会允许他的存在
直接改成
window.Mustache = mustache;
将他定义在window对象上
然后 我们html代码编写如下
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<script src = "./js/mustache.js">script>
<script>
console.log(Mustache);
script>
body>
html>
这里 我们引入了mustache.js 然后利用console.log将Mustache对象输出在浏览器控制台上
然后我们运行html文件
打开控制台
就可以看到 我们的Mustache对象就被输出在了控制台上
大家会发现 这里有个 render 方法
这和react渲染元素的生命周期是如出一辙
没错mustache 就要用它渲染界面
话说 那我们还是继续来实现上文中的那个需求
我们将html代码修改如下
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<script src = "./js/mustache.js">script>
<script>
var data = {
list: [
{
"name": "小猫猫",
"age": 12,"sex":"男"
},
{
"name":"小红",
"age": 11,
"sex":"女"
},{
"name":"小强",
"age": 13,
"sex":"男"
}
]
};
var templateStr = `
{{ #list }}
-
{{ name }}
{{ /list }}
`;
let html = Mustache.render(templateStr, data);
console.log(html);
script>
body>
html>
我们这里定义了数据data 将上文那个对象数组 放进了data对象中的list字段中
然后 我们定义了一个templateStr模板字符串 里面写的就是我们页面体
然后 我们先定义外面一个ul
然后 开启循环语句 换行的是list 这样 他就会找 render接到的第二个参数中的list字段
然后循环遍历他 里面写的 {{ name }} 就是取循环出来的每个下标的name值
然后调用Mustache中的render 第一个参数 需要一个页面体的模板字符串 用于渲染
第二个参数需要渲染时用到的一个对象数据
然后 我们将render函数返回的结果定义给了html 变量 然后在控制台输出
运行结果如下
可以看到 这样 我们就会去到了一个界面格式的html字符串
当然 mustache 不会帮你上树
你得到这个字符串 需要自己去上树
将html代码改成这样
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div id = "list">div>
<script src = "./js/mustache.js">script>
<script>
var data = {
list: [
{
"name": "小猫猫",
"age": 12,"sex":"男"
},
{
"name":"小红",
"age": 11,
"sex":"女"
},{
"name":"小强",
"age": 13,
"sex":"男"
}
]
};
var templateStr = `
{{ #list }}
-
{{ name }}
{{ /list }}
`;
document.getElementById('list').innerHTML = Mustache.render(templateStr, data);
script>
body>
html>
循环语句中 大家一定要记住 不是一定要叫list啊
简单说 就是 {{ #需要循环的字段 }} 内容 {{ /需要循环的字段 }}
这样就可以了
然后 我们来看一下不循环的写法
html代码修改如下
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div id = "list">div>
<script src = "./js/mustache.js">script>
<script>
var data = {
name: "小猫猫",
age: 2
};
var templateStr = `我是一只{{ name }},我今年{{ age }}岁啦
`;
document.getElementById('list').innerHTML = Mustache.render(templateStr, data);
script>
body>
html>
我们可以看到 我们直接通过 {{ 属性名 }} 就可以像vue的写法一样 去那响应式数据了
然后 我们打开界面
也是没有任何问题
然后 我们来看另一种用法
遍历非对象数组
我们将html代码修改如下
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div id = "list">div>
<script src = "./js/mustache.js">script>
<script>
var data = {
arr: [
"小明",
"小光",
"小猫猫"
]
};
var templateStr = `
{{ #arr }}
{{ . }}
{{ /arr }}
`;
document.getElementById('list').innerHTML = Mustache.render(templateStr, data);
script>
body>
html>
这里 我们在data中将arr定义为一个字符串数组
然后 在循环中 如果你想用数组下标 用一个 . 就行了
运行结果如下
然后 我们来处理多层数组嵌套的逻辑
我们这样编写代码
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div id = "list">div>
<script src = "./js/mustache.js">script>
<script>
var data = {
list: [
{
name: "小明",
hobby: [
"羽毛球",
"游泳"
]
},
{
name: "小光",
hobby: [
"游戏"
]
},
{
name: "小猫猫",
hobby: [
"唱跳",
"rap",
"篮球"
]
}
]
};
var templateStr = `
{{ #list }}
{{ name }}
{{ #hobby }}
{{ . }}
{{ /hobby }}
{{ /list }}
`;
document.getElementById('list').innerHTML = Mustache.render(templateStr, data);
script>
body>
html>
可以看到 我们对象数组中每一个下标对象里面又有一个数组hobby
这样 我们只需要在遍历的语法中再用变量就好了
运行结果如下
我一般管这种一层一层的叫俄罗斯套娃
然后 我们再来看看 一个类似于 v-if的语法
但是大家要先搞清楚 mustache 是识别不了表达式的 你要是写 arr == 1 mustache是识别不了的
他的判断 你只能给 false或 true
我们将html代码改成这样
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div id = "list">div>
<script src = "./js/mustache.js">script>
<script>
var data = {
bint: true
};
var templateStr = `
{{ #bint }}
你好
{{ /bint }}
`;
document.getElementById('list').innerHTML = Mustache.render(templateStr, data);
script>
body>
html>
此时 我们语法判断了bint那么 data中的 bint 值是true 说明 这个内容是可以展示的 我们运行代码
然后 我们这次将 bint改为false
运行代码
可以看到 这下就啥都没了
然后 我们再来看个比较好玩的东西
我们这里 直接在js部分去写一个html代码
可以看到 这样 我们控制台就报错了 js也不继续往下走了
但是我们可以这样写
<script type="text/template">
<div>你好</div>
script>
其实这个text/template只是因为 template 有模板的意思 而且后面大家都这样写 就约定俗成了 但其实这个东西浏览器是不识别的
简单说 就是 script 标签中的type 你都可以乱写 反正就是要让浏览器读不懂 他就不会读这里面的脚本
将页面结构写在这里面 然后我们运行界面就一起正常了
我们可以这样编写html代码
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div id = "list">div>
<script src = "./js/mustache.js">script>
<script type="text/template" id="mytemplate">
<div>
{{ #list }}
<h1> {{ . }} </h1>
{{ /list }}
</div>
script>
<script>
var data = {
list: [
"嗨",
"飞来"
]
};
var templateStr = document.getElementById('mytemplate').innerHTML;
document.getElementById('list').innerHTML = Mustache.render(templateStr, data);
script>
body>
html>
我们就用刚刚改变script的type的方法将页面模板放进去了 然后 定义了一个id
然后 templateStr 直接通过id 拿到我们写在模板里的内容
渲染在界面上
后面我们就不是使用了 后续会了解并书写这个东西的底层逻辑