上文 探究Vue源码:mustache模板引擎(9) 将单层无喜欢结果tokens转为dom字符串 我们简单处理了 token转字符串的业务逻辑
但是 我们只处理了最贱的花括号
接下来 带着大家将井号的也处理一下
我们打开项目 将 www中的index.html代码改回之前的这样
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<script src = "/xuni/bundle.js">script>
<script>
let templateStr = `
{{#students}}
- {{ item.name }}
{{#item.list}}
- {{ . }}
{{/item.list}}
{{/students}}
`;
let data = {
name: "小猫猫",
age: 2,
students: [
{
id: 0,
name: "小明",
list: [
"篮球",
"唱",
"跳"
]
},
{
id: 1,
name: "小红",
list: [
"电子游戏",
"计算机编程"
]
}
]
}
GrManagData.render(templateStr,data);
script>
body>
html>
我们来处理一下这个循环嵌套的结构
然后 我们运行项目 会发现 到 井号位置就有问题了 它无法处理
这里 我们显然 用平行的结构是搞不定的 需要递归
首先 我们可以想一很简单的思路 不带井号 是调用renderTemplate
那么 我们带井号的 不就可以递归去调用这个 renderTemplate 吗?
是不是 思路非常简单
但在写递归之前 我们先要解决一个问题
例如 我们将 www 下的 index.html
改成这样
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<script src = "/xuni/bundle.js">script>
<script>
let templateStr = `
我超喜欢我家的{{name}},我家{{name}}也超喜欢我,它今年{{a.b.c}}岁啦
`;
let data = {
name: "小猫猫",
a: {
b: {
c: 2
}
}
}
GrManagData.render(templateStr,data);
script>
body>
html>
这样 我们在语句中 用了 data中的 a对象下的 b 对象下的c对象
然后我们运行项目
这里 直接成了undefined 因为 他无法识别 点这个语法 就是 你用对象名点字段名 我们写的这个
它没办法识别
其实 我们可以打印一下 看看这里 a.b.c 它生成的name是什么样的
我们这里 用console.log 看看里面到底是个什么
没错 这里 拿到的确实是 a.b.c
但你现在的语法相当于
data["a.b.c"]
这里 我们 js这个括号 只支持找直接下标 他是不认识我们这个点的语法的 他不会帮你往下找
所以 这里就有问题了
真的这个问题
我们在src下再创建一个 lookup.js
先放上这样一段代码
/*
可以在data中,用连续点符号的形式找到对应键值
*/
export default function lookup(data,keyName) {
}
先暴露一个函数出去
这个函数 需要两个参数 第一个是总的data 你要找 肯定要给总的数据嘛 对不对?
然后 第二参数 是字段名 例如 a.b.c
写完这个函数 就可以取到 对象中的对象中的对象了
我们将 lookup 内容改成这样
/*
可以在data中,用连续点符号的形式找到对应键值
*/
export default function lookup(data,keyName) {
//判断keyName字符串中是否有 . 符号
if(keyName.indexOf(".") > 0) {
//将keyName按点拆分成数组
var names = keyName.split('.');
//存一个 指向 data 的临时变量
let temp = data;
//循环遍历 用点拆分开的数组names
for(let i = 0;i < names.length;i++) {
// 一层一层寻找对应字段
temp = temp[names[i]];
}
//将得到的结果返回
return temp;
}
//没有 点符号 就直接将data中的keyName字段返回就ok了
return data[keyName]
}
进来 我们先判断keyName 有没有点符号
如果有 走进来 我们利用字符串拆分的split将他拆开成数组
然后用一个零时变量将data存起来
然后我们循环我们用 点 符号拆开的这个数组 那么 内容自然是 [“a”,“b”,“c”]
那么 循环一次内容 就是 a b c
那么 第一次进来 temp 的值指向的是 data 第一个下标 是 a 就是找到 data下的a
第二次 temp 目前是data下的a 然后 第二个下标是 b 就是 在a下寻找b
第三次 就成立 b下寻找c
非常简单 最后处理好将temp返回回去
如果没有点符号 没有走进if 那就更简单 直接 找data下的keyName值
然后 我们将
src下的 renderTemplate.js 代码改一下