Explore Vue source code: mustache template engine (11) recursively process loop logic and finish algorithm processing

Fortunately, we explored the Vue source code above: mustache template engine (10) to solve the problem of not being able to find multi-layer objects with continuous dot symbols, and to pave the way for the compilation cycle structure. We solved the problem that the js string cannot get the value in the object through what point or something This question
needs to be remembered because this method was written as an interview question before.

Then in this article, we are going to write the recursion mentioned above. Find renderTemplate.js
and add a condition below the judgment here.
Judging that if the current first subscript is a pound sign, the logic of opening a new one
insert image description here
is what we said before. Can handle text and name types, but he has no processing ability in the way of number sign cycle

We will change the index.html code under www to this

<!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>{
       
       { name }}</li>
                        {
       
       {#list}}
                            <li>{
       
       { . }}</li>
                        {
       
       {/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>

Let's create a parseArray.js file under src and write and expose a function first.

/*
    处理数组逻辑
*/
export default function parseArray(token,data) {
    
    
    console.log(token,data);
}

Here our function receives two parameters, token, which is a single subscript of tokens, and data, which is the overall data.
There is nothing to say.
This function is used to process the logic of the array loop.

Here we import and call renderTemplate.js
Here we judge the cycle number and throw it directly to it for processing.
insert image description here
After running the project, we find that the token and the overall data of our data are printed out,
insert image description here
which means that the data of parseArray is still obtained
, and then parseArray needs to call renderTemplate call cyclically The number of times depends on the length of the traversal array
, but first we need to take out this array from data
, so we need lookup, which
we can import and then write like this.
insert image description here
The result of the operation is as follows.
insert image description here
You can see that the syntax successfully outputs the contents of students in our data
insert image description here
, and here we write a simple
Change the index.html code under www to the following

<!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>{
       
       {name}}</li>
                    </ul>
                {
       
       {/students}}
            </div>
        `;
        let data = {
      
      
            name: "小猫猫",
            age: 2,
            students: [
                {
      
      
                    id: 0,
                    name: "小明",
                    list: [
                        "篮球",
                        "唱",
                        "跳"
                    ]
                },
                {
      
      
                    id: 1,
                    name: "小红",
                    list: [
                        "电子游戏",
                        "计算机编程"
                    ]
                }
            ]
        }
        GrManagData.render(templateStr,data);
    </script>
</body>
</html>

Here we don't engage in multi-level nesting, we need a first-level loop
, and then we change the final output of renderTemplate to return.
insert image description here
Here we change it to return after processing and then return directly.
Then parseArray.js code is written as follows

import lookup from "./lookup";
import renderTemplate from "./renderTemplate";

/*
    处理数组逻辑
*/
export default function parseArray(token,data) {
    
    
    let view = lookup(data,token[1]);
    let resultStr = "";
    for(let i = 0; i < view.length; i++) {
    
    
        resultStr += renderTemplate(token[2],view[i]);
    }
    return resultStr;
}

Here we get the traversed array and loop through the view
, then define a resultStr to store the content generated by loop traversal , and then call renderTemplate for each loop to accept the returned result. The token[2] here is
because when we wrote nestTokens.
The tokens structure has the 2 subscripts of the pound token. I don’t know if you still remember.
insert image description here
Then view[i] is the subscript currently being cycled. For example, the array structure is

[
    {
    
    id: 1,name:"你好"},
    {
    
    id: 2,name:"小猫猫"}
]

Then the first cycle i is 0, view[i] is view[0] and the corresponding value is {id: 1, name: "Hello"} and so on. Use the subscript of the current cycle as the
data
source and then use the second The subscripted token is the page structure inside the loop.
The result of the operation is as follows.
insert image description here
We have completed a simple version

But there is still a problem at present, that is, if our array structure is simpler, there will still be problems.
We will change the index.html code under www as follows

<!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>{
       
       {.}}</li>
                    </ul>
                {
       
       {/students}}
            </div>
        `;
        let data = {
      
      
            name: "小猫猫",
            age: 2,
            students: [
                "小明",
                "小芳"
            ]
        }
        GrManagData.render(templateStr,data);
    </script>
</body>
</html>

The result of the operation is as follows
insert image description here
, it directly becomes undefined
because our level is unable to recognize the meaning of this small point. In mustache, the small point means directly taking the subscript of the current number

We can directly change parseArray to

export default function parseArray(token,data) {
    
    
    let view = lookup(data,token[1]);
    let resultStr = "";
    for(let i = 0; i < view.length; i++) {
    
    
        resultStr += renderTemplate(token[2],{
    
    ".": view[i]});
    }
    return resultStr;
}

It’s equivalent to writing an object whose key is “.”, and the value is the current item of the array itself. The result is as follows.
Writing
insert image description here
this way can indeed solve the problem, but putting the format of the array object before it will ruin
us again. Restore the index.html under www to our previous appearance.
insert image description here
After running, it will be undefined,
insert image description here
because the object you passed is data. When we set it up like this, it only has one field, which is the dot

Here we change this sentence to this

resultStr += renderTemplate(token[2],{
    
    ".": view[i],...view[i]});

insert image description here
Here we assign all the fields of the current object to this object through the ES feature of three small points

In this way, we change the index.html under www back, and
insert image description here
this mode can also be adapted
insert image description here
. Not only can they all be able to have a multi-layer nested structure, but now
we can change the index.html code under www to

<!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>{
       
       {name}}</li>
                        {
       
       {#list}}
                            <li>{
       
       {.}}</li>
                        {
       
       {/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>

Then we change the judgment of lookup.js.
insert image description here
Simply put, our name can contain dots, but it cannot be a dot. It is a dot itself. The
final running result is as follows, which
insert image description here
is perfect

Then we will change the function in index.js for the last time,
insert image description here
we will return directly without output

Then we modify the index.html code under www as follows

<!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>
    <div id = "container"></div>
    <script src = "/xuni/bundle.js"></script>
    <script>
        let templateStr = `
            <div>
                {
       
       {#students}}
                    <ul>
                        <li>{
       
       {name}}</li>
                        {
       
       {#list}}
                            <li>{
       
       {.}}</li>
                        {
       
       {/list}}
                    </ul>
                {
       
       {/students}}
            </div>
        `;
        let data = {
      
      
            name: "小猫猫",
            age: 2,
            students: [
                {
      
      
                    id: 0,
                    name: "小明",
                    list: [
                        "篮球",
                        "唱",
                        "跳"
                    ]
                },
                {
      
      
                    id: 1,
                    name: "小红",
                    list: [
                        "电子游戏",
                        "计算机编程"
                    ]
                }
            ]
        }
        let templateDom = GrManagData.render(templateStr,data);
        var container = document.getElementById('container');
        container.innerHTML = templateDom;
    </script>
</body>
</html>

The results of the operation are as follows
insert image description here
. Congratulations to everyone who has reached the end

Guess you like

Origin blog.csdn.net/weixin_45966674/article/details/132145559