上文 探究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>Document</title>
</head>
<body><script src = "/xuni/bundle.js"></script><script>let templateStr = `<div>{{#students}}<ul><li>{{ item.name }}</li>{{#item.list}}<li>{{ . }}</li>{{/item.list}}</ul>{{/students}}</div>`;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>Document</title>
</head>
<body><script src = "/xuni/bundle.js"></script><script>let templateStr = `<div>我超喜欢我家的{{name}},我家{{name}}也超喜欢我,它今年{{a.b.c}}岁啦</div>`;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;//循环遍历 用点拆分开的数组namesfor(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 代码改一下
这里 我们引入并使用一下lookup
运行项目
可以看到 这些数据就读到啦