探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫

上文 探究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>

我们来处理一下这个循环嵌套的结构

然后 我们运行项目 会发现 到 井号位置就有问题了 它无法处理
探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫_第1张图片
这里 我们显然 用平行的结构是搞不定的 需要递归
首先 我们可以想一很简单的思路 不带井号 是调用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对象
然后我们运行项目
探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫_第2张图片
这里 直接成了undefined 因为 他无法识别 点这个语法 就是 你用对象名点字段名 我们写的这个
探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫_第3张图片
它没办法识别

其实 我们可以打印一下 看看这里 a.b.c 它生成的name是什么样的
探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫_第4张图片
我们这里 用console.log 看看里面到底是个什么
探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫_第5张图片

没错 这里 拿到的确实是 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 代码改一下

这里 我们引入并使用一下lookup
探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫_第6张图片
运行项目
探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫_第7张图片
可以看到 这些数据就读到啦
探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫_第8张图片

你可能感兴趣的:(vue.js,javascript,前端)